UnsafeHeterogeneousBuffer

codecov License: MIT

概述

工作流程 CI 状态
兼容性测试 Compatibility tests
macOS 单元测试 macOS
iOS 单元测试 iOS
Ubuntu 22.04 单元测试 Ubuntu

入门指南

在你的 Package.swift 文件中,将以下依赖项添加到你的 dependencies 参数中

.package(url: "https://github.com/OpenSwiftUIProject/UnsafeHeterogeneousBuffer.git", from: "0.1.0"),

然后将依赖项添加到你在清单文件中声明的任何目标中

.target(
    name: "MyTarget", 
    dependencies: [
        .product(name: "UnsafeHeterogeneousBuffer", package: "UnsafeHeterogeneousBuffer"),
    ]
),

用法

基本用法

要使用 UnsafeHeterogeneousBuffer,首先创建你的 VTable 实现,然后使用 append 方法将元素添加到缓冲区。

import UnsafeHeterogeneousBuffer

final class VTable<Value>: _UnsafeHeterogeneousBuffer_VTable {
    override class func hasType<T>(_ type: T.Type) -> Bool {
        Value.self == T.self
    }
    
    override class func moveInitialize(elt: _UnsafeHeterogeneousBuffer_Element, from: _UnsafeHeterogeneousBuffer_Element) {
        let dest = elt.body(as: Value.self)
        let source = from.body(as: Value.self)
        dest.initialize(to: source.move())
    }
    
    override class func deinitialize(elt: _UnsafeHeterogeneousBuffer_Element) {
        elt.body(as: Value.self).deinitialize(count: 1)
    }
}

var buffer = UnsafeHeterogeneousBuffer()
defer { buffer.destroy() }      
_ = buffer.append(UInt32(1), vtable: VTable<Int32>.self)
_ = buffer.append(Int(-1), vtable: VTable<Int>.self)
_ = buffer.append(Double.infinity, vtable: VTable<Double>.self)

高级用法

或者你可以在内部使用 UnsafeHeterogeneousBuffer 来实现你自己的缓冲区类型。

public protocol P {
    mutating func modify(inputs: inout Int)
}

extension P {
    public mutating func modify(inputs: inout Int) {}
}

public final class A {
    private var buffer = PBuffer(contents: .init())

    package func append<T>(t: T) where T: P {
        buffer.append(t)
    }
    
    package subscript<T>(t: T.Type) -> UnsafeMutablePointer<T>? where T: P {
        buffer[t]
    }

    deinit {
        buffer.contents.destroy()
    }
}

struct PBuffer {
    var contents: UnsafeHeterogeneousBuffer

    @discardableResult
    mutating func append<T>(_ t: T) -> UnsafeHeterogeneousBuffer.Index where T: P {
        contents.append(t, vtable: _VTable<T>.self)
    }
    
    subscript<T>(_ type: T.Type) -> UnsafeMutablePointer<T>? where T: P {
        guard !contents.isEmpty else { return nil }
        for elelement in contents  {
            guard elelement.hasType(type) else {
                continue
            }
            return elelement.body(as: type)
        }
        return nil
    }
    
    typealias Index = UnsafeHeterogeneousBuffer.Index
    
    struct Element {
        var base: UnsafeHeterogeneousBuffer.Element
    }

    var startIndex: UnsafeHeterogeneousBuffer.Index { contents.startIndex }
    
    var endIndex: UnsafeHeterogeneousBuffer.Index { contents.endIndex }
    
    var isEmpty: Bool { contents.isEmpty }
    
    subscript(position: UnsafeHeterogeneousBuffer.Index) -> Element {
        _read { yield Element(base: contents[position]) }
    }
    
    func index(after i: UnsafeHeterogeneousBuffer.Index) -> UnsafeHeterogeneousBuffer.Index {
        contents.index(after: i)
    }
    
    private class VTable: _UnsafeHeterogeneousBuffer_VTable {
        class func modify(elt: UnsafeHeterogeneousBuffer.Element, inputs: inout Int) {}
    }
    
    private final class _VTable<T>: VTable where T: P{
        override class func modify(elt: UnsafeHeterogeneousBuffer.Element, inputs: inout Int) {
            elt.body(as: T.self).pointee.modify(inputs: &inputs)
        }
    }
}

请访问 UnsafeHeterogeneousBuffer 文档站点 以获取有关该库的更多详细信息。

许可证

请参阅 LICENSE 文件 - MIT

相关项目

Star 历史

Star History Chart