Property Wrapper is also useful.
@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
}
}
struct Person: Equatable {
var name: String
}
struct Team: Equatable {
@CopyOnWriteBox
var leader: Person
}
var t1 = Team(leader: Person(name: "aaa"))
t1.leader.name = "bbb"