Skip to content

Instantly share code, notes, and snippets.

@dabrahams
Created March 31, 2017 03:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dabrahams/2a530f0925194555fa65374c2b277a2e to your computer and use it in GitHub Desktop.
Save dabrahams/2a530f0925194555fa65374c2b277a2e to your computer and use it in GitHub Desktop.
A way to ask about uniqueness of class references, without a struct wrapper
extension ObjectIdentifier {
/// Returns true if the object identified by `self` is uniquely referenced.
///
/// - Requires: the object identified by `self` exists.
/// - Note: will only work when called from a mutating method
internal func _liveObjectIsUniquelyReferenced() -> Bool {
var me = self
return withUnsafeMutablePointer(to: &me) {
$0.withMemoryRebound(to: AnyObject.self, capacity: 1) {
_isUnique(&$0.pointee)
}
}
}
}
protocol COWBuffer { }
extension COWBuffer {
var id: ObjectIdentifier {
if let _=Self.self as? AnyObject.Type, let me = self as Any as? AnyObject {
return ObjectIdentifier(me)
}
fatalError()
}
mutating func isUniquelyReferenced() -> Bool {
defer { _fixLifetime(self) }
return id._liveObjectIsUniquelyReferenced()
}
mutating func mutate<R>(body: (inout Self)->R) -> R {
return body(&self)
}
}
class X : COWBuffer {
init() { }
}
func test() {
var x1 = X()
x1.mutate { print($0.isUniquelyReferenced() ? "in-place" : "copy") }
do
{
var x2 = x1
x1.mutate { print($0.isUniquelyReferenced() ? "in-place": "copy")}
x2.mutate { print($0.isUniquelyReferenced() ? "in-place": "copy")}
}
x1.mutate { print($0.isUniquelyReferenced() ? "in-place": "copy")}
}
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment