Workflow | CI Status |
---|---|
Compatibility Test | |
macOS Unit Test | |
iOS Unit Test | |
Ubuntu 22.04 Unit Test |
In your Package.swift
file, add the following dependency to your dependencies
argument:
.package(url: "https://github.com/OpenSwiftUIProject/UnsafeHeterogeneousBuffer.git", from: "0.1.0"),
Then add the dependency to any targets you've declared in your manifest:
.target(
name: "MyTarget",
dependencies: [
.product(name: "UnsafeHeterogeneousBuffer", package: "UnsafeHeterogeneousBuffer"),
]
),
To make use of UnsafeHeterogeneousBuffer
, first create your VTable
implementation and then
use append
method to add elements to the buffer.
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)
Or you can use UnsafeHeterogeneousBuffer
internally to implement your own buffer type.
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)
}
}
}
Please see UnsafeHeterogeneousBuffer documentation site for more detailed information about the library.
See LICENSE file - MIT