Skip to content

Instantly share code, notes, and snippets.

@tkersey
Created July 8, 2022 02:12
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 tkersey/46489cef0b91522ee6658b03d91684c8 to your computer and use it in GitHub Desktop.
Save tkersey/46489cef0b91522ee6658b03d91684c8 to your computer and use it in GitHub Desktop.
Reducing stack costs of structs by using Copy on Write (CoW)
@propertyWrapper
struct CopyOnWriteBox<Value> {
private var ref: Ref<Value>
init(wrappedValue: Value) {
self.ref = Ref(wrappedValue)
}
var wrappedValue: Value {
get {
ref.value
}
set {
if isKnownUniquelyReferenced(&ref) {
ref.value = newValue
} else {
ref = Ref(newValue)
}
}
}
private final class Ref<T> {
var value: T
init(_ value: T) {
self.value = value
}
}
}
extension CopyOnWriteBox: Equatable where Value: Equatable {
static func == (lhs: Self<Value>, rhs: Self<Value>) -> Bool {
lhs.ref.value == rhs.ref.value
}
}
@dynamicMemberLookup
struct CoW<T> {
init(_ value: T) {
_storage = Storage(value)
}
public subscript<V>(dynamicMember keyPath: WritableKeyPath<T, V>) -> V {
get { value[keyPath: keyPath] }
set { value[keyPath: keyPath] = newValue }
}
var value: T {
get {
return _storage.value
}
set {
if isKnownUniquelyReferenced(&_storage) {
_storage.value = value
} else {
_storage = Storage(newValue)
}
}
}
private var _storage: Storage<T>
private class Storage<T> {
var value: T
init(_ value: T) {
self.value = value
}
}
}
extension CoW: Equatable where T: Equatable {
static func == (lhs: CoW<T>, rhs: CoW<T>) -> Bool {
return lhs.value == rhs.value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment