diff --git a/Sources/Swexy/Utilities/Atomic.swift b/Sources/Swexy/Utilities/Atomic.swift index b06355f..d1f23a3 100644 --- a/Sources/Swexy/Utilities/Atomic.swift +++ b/Sources/Swexy/Utilities/Atomic.swift @@ -8,24 +8,45 @@ import Foundation @propertyWrapper -public class Atomic { - private var _wrappedValue: T +public enum Atomic { + case atomic(innerValue: T, semaphore: DispatchSemaphore) + + @usableFromInline typealias MemoryLayout = (T, DispatchSemaphore) + + @usableFromInline var memoryLayout: MemoryLayout { + @_transparent get { + unsafeBitCast(self, to: MemoryLayout.self) + } + } + + @_transparent @usableFromInline var semaphore: DispatchSemaphore { + memoryLayout.1 + } + + @usableFromInline var _wrappedValue: T { + @_transparent get { + memoryLayout.0 + } + @_transparent set { + self = .atomic(innerValue: newValue, semaphore: semaphore) + } + } - private let semaphore = DispatchSemaphore(value: 1) public var wrappedValue: T { - _read { + @_transparent get { semaphore.wait() - yield _wrappedValue + let returnValue = _wrappedValue semaphore.signal() + return returnValue } - _modify { + @_transparent set { semaphore.wait() - yield &_wrappedValue + _wrappedValue = newValue semaphore.signal() } } - public init(wrappedValue: T) { - _wrappedValue = wrappedValue + @_transparent public init(wrappedValue: T) { + self = .atomic(innerValue: wrappedValue, semaphore: DispatchSemaphore(value: 1)) } }