Skip to content

OpenSwiftUIProject/UnsafeHeterogeneousBuffer

Repository files navigation

UnsafeHeterogeneousBuffer

codecov License: MIT

Overview

Workflow CI Status
Compatibility Test Compatibility tests
macOS Unit Test macOS
iOS Unit Test iOS
Ubuntu 22.04 Unit Test Ubuntu

Getting Started

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"),
    ]
),

Usage

Plain usage

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)

Advanced usage

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.

License

See LICENSE file - MIT

Related Projects

Star History

Star History Chart

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published