Repository: apple/swift-nio
File: Sources/NIOConcurrencyHelpers/NIOAtomic.swift (Swift)

Code before:
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import CNIOAtomics

/// The protocol that all types that can be made atomic must conform to.
///
/// **Do not add conformance to this protocol for arbitrary types**. Only a small range
/// of types have appropriate atomic operations supported by the CPU, and those types
/// already have conformances implemented.
#if compiler(>=6.0)
@preconcurrency
public protocol NIOAtomicPrimitive {
    associatedtype AtomicWrapper
    static var nio_atomic_create_with_existing_storage: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
    static var nio_atomic_compare_and_exchange: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self, Self) -> Bool { get }
    static var nio_atomic_add: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_sub: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_exchange: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_load: @Sendable (UnsafeMutablePointer<AtomicWrapper>) -> Self { get }
    static var nio_atomic_store: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
}
#else
public protocol NIOAtomicPrimitive {
    associatedtype AtomicWrapper
    static var nio_atomic_create_with_existing_storage: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
    static var nio_atomic_compare_and_exchange: (UnsafeMutablePointer<AtomicWrapper>, Self, Self) -> Bool { get }
    static var nio_atomic_add: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_sub: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_exchange: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_load: (UnsafeMutablePointer<AtomicWrapper>) -> Self { get }
    static var nio_atomic_store: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
}
#endif

extension Bool: NIOAtomicPrimitive {
    public typealias AtomicWrapper = catmc_nio_atomic__Bool
    public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic__Bool_create_with_existing_storage
    public static let nio_atomic_compare_and_exchange = catmc_nio_atomic__Bool_compare_and_exchange
    public static let nio_atomic_add = catmc_nio_atomic__Bool_add
    public static let nio_atomic_sub = catmc_nio_atomic__Bool_sub
    public static let nio_atomic_exchange = catmc_nio_atomic__Bool_exchange
    public static let nio_atomic_load = catmc_nio_atomic__Bool_load
    public static let nio_atomic_store = catmc_nio_atomic__Bool_store
}

extension Int8: NIOAtomicPrimitive {
    public typealias AtomicWrapper = catmc_nio_atomic_int_least8_t
    public static let nio_atomic_create_with_existing_storage =
        catmc_nio_atomic_int_least8_t_create_with_existing_storage

Review comment (refactor):
Unfortunately, this change to duplicate the protocol definition was required because Swift 5.8, 5.9, and 5.10 do not support `InferSendableFromCaptures`.

Code after:
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import CNIOAtomics

/// The protocol that all types that can be made atomic must conform to.
///
/// **Do not add conformance to this protocol for arbitrary types**. Only a small range
/// of types have appropriate atomic operations supported by the CPU, and those types
/// already have conformances implemented.
#if compiler(>=6.0)
@preconcurrency
public protocol NIOAtomicPrimitive {
    associatedtype AtomicWrapper
    static var nio_atomic_create_with_existing_storage: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void {
        get
    }
    static var nio_atomic_compare_and_exchange: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self, Self) -> Bool {
        get
    }
    static var nio_atomic_add: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_sub: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_exchange: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_load: @Sendable (UnsafeMutablePointer<AtomicWrapper>) -> Self { get }
    static var nio_atomic_store: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
}
#else
public protocol NIOAtomicPrimitive {
    associatedtype AtomicWrapper
    static var nio_atomic_create_with_existing_storage: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
    static var nio_atomic_compare_and_exchange: (UnsafeMutablePointer<AtomicWrapper>, Self, Self) -> Bool { get }
    static var nio_atomic_add: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_sub: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_exchange: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
    static var nio_atomic_load: (UnsafeMutablePointer<AtomicWrapper>) -> Self { get }
    static var nio_atomic_store: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
}
#endif

extension Bool: NIOAtomicPrimitive {
    public typealias AtomicWrapper = catmc_nio_atomic__Bool
    public static let nio_atomic_create_with_existing_storage = catmc_nio_atomic__Bool_create_with_existing_storage
    public static let nio_atomic_compare_and_exchange = catmc_nio_atomic__Bool_compare_and_exchange
    public static let nio_atomic_add = catmc_nio_atomic__Bool_add
    public static let nio_atomic_sub = catmc_nio_atomic__Bool_sub
    public static let nio_atomic_exchange = catmc_nio_atomic__Bool_exchange
    public static let nio_atomic_load = catmc_nio_atomic__Bool_load
    public static let nio_atomic_store = catmc_nio_atomic__Bool_store
}