A copy-on-write is usually a struct
wrapper over some backing object.
public final class MutableHeapStore<T>: NonObjectiveCBase
{
public typealias Storage = T
public private(set) var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
}
public struct COW<T>
{
public typealias Storage = MutableHeapStore<T>
public typealias Value = T
public var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
public var value: Value
{
get
{
return storage.storage
}
set
{
if isUniquelyReferenced(&storage)
{
storage.storage = newValue
}
else
{
storage = Storage(storage: newValue)
}
}
}
public init(_ value: Value)
{
self.init(storage: Storage(storage: value))
}
}
extension COW: CustomStringConvertible
{
public var description: String
{
return String(value)
}
}
The trick lies in asserting isUniquelyReferenced
every time the boxed value is mutated. If the underlying storage object is singly referenced, nothing is to be done. However if another reference exists, one must create a new storage.
Is this code thread-safe? It is exactly as safe as any other value type, e.g. Int
or Bool
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…