Skip to content

Instantly share code, notes, and snippets.

@klundberg
Last active April 1, 2017 23:27
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 klundberg/9faf7b934fc2ecbaa8d9fa414905ba7c to your computer and use it in GitHub Desktop.
Save klundberg/9faf7b934fc2ecbaa8d9fa414905ba7c to your computer and use it in GitHub Desktop.
Encapsulating copy-on-write behavior in a reusable way.
// Written using Swift 3.0.x
fileprivate final class Box<T> {
let unbox: T
init(_ value: T) {
unbox = value
}
}
public struct CopyOnWrite<T: AnyObject> {
private var _reference: Box<T>
private let copy: (T) -> T
public init(reference: T, copy: @escaping (T) -> T) {
self._reference = Box(reference)
self.copy = copy
}
public var reference: T {
return _reference.unbox
}
public var mutatingReference: T {
mutating get {
// copy the reference only if necessary
if !isKnownUniquelyReferenced(&_reference) {
_reference = Box(self.copy(_reference.unbox))
}
return _reference.unbox
}
}
}
public protocol Cloneable: class {
func clone() -> Self
}
extension CopyOnWrite where T: Cloneable {
public init(reference: T) {
self.init(reference: reference, copy: { $0.clone() })
}
}
import Foundation
extension CopyOnWrite where T: NSCopying {
public init(copyingReference reference: T) {
self.init(reference: reference, copy: { $0.copy() as! T })
}
}
extension CopyOnWrite where T: NSMutableCopying {
public init(mutableCopyingReference reference: T) {
self.init(reference: reference, copy: { $0.mutableCopy() as! T })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment