[swift-users] komihåg swift 4 Vector

Jens Persson jens at bitcycle.com
Mon Jul 10 12:45:56 CDT 2017


protocol VectorStorage {
    associatedtype A
    associatedtype B
    associatedtype C
    associatedtype D
    var elements: (A, B, C, D) { get set }
    init(elements: (A, B, C, D))
}
struct VectorStorage2<T> : VectorStorage {
    var elements: (T, T, Void, Void)
}
struct VectorStorage3<T> : VectorStorage {
    var elements: (T, T, T, Void)
}

protocol VectorIndex {
    associatedtype StorageOf8BitElements: VectorStorage
    associatedtype StorageOf16BitElements: VectorStorage
    associatedtype StorageOf32BitElements: VectorStorage
    associatedtype StorageOf64BitElements: VectorStorage
    static func vectorStorage<V: Vector>(for: V.Type, from fn: (Self) ->
V.Element) -> V.Storage
        where V.Index == Self
    func getElement<V: Vector>(from: V) -> V.Element where V.Index == Self
    func setElement<V: Vector>(of vector: inout V, to value: V.Element)
where V.Index == Self
}
enum Index2 : VectorIndex {
    typealias StorageOf8BitElements = VectorStorage2<UInt8>
    typealias StorageOf16BitElements = VectorStorage2<UInt16>
    typealias StorageOf32BitElements = VectorStorage2<UInt32>
    typealias StorageOf64BitElements = VectorStorage2<UInt64>
    case i0, i1
    static func vectorStorage<V: Vector>(for: V.Type, from fn: (Index2) ->
V.Element) -> V.Storage
        where V.Index == Index2
    {
        let storage = V.Storage.init(elements: (
            unsafeBitCast(fn(.i0), to: V.Storage.A.self),
            unsafeBitCast(fn(.i1), to: V.Storage.B.self),
            () as! V.Storage.C,
            () as! V.Storage.D
        ))
        return storage
    }
    func getElement<V: Vector>(from vector: V) -> V.Element where V.Index
== Index2 {
        switch self {
        case .i0: return unsafeBitCast(vector.storage.elements.0, to:
V.Element.self)
        case .i1: return unsafeBitCast(vector.storage.elements.1, to:
V.Element.self)
        }
    }
    func setElement<V: Vector>(of vector: inout V, to value: V.Element)
where V.Index == Index2 {
        switch self {
        case .i0: vector.storage.elements.0 = unsafeBitCast(value, to:
V.Storage.A.self)
        case .i1: vector.storage.elements.1 = unsafeBitCast(value, to:
V.Storage.B.self)
        }
    }
}
enum Index3 : VectorIndex {
    typealias StorageOf8BitElements = VectorStorage3<UInt8>
    typealias StorageOf16BitElements = VectorStorage3<UInt16>
    typealias StorageOf32BitElements = VectorStorage3<UInt32>
    typealias StorageOf64BitElements = VectorStorage3<UInt64>
    case i0, i1, i2
    static func vectorStorage<V: Vector>(for: V.Type, from fn: (Index3) ->
V.Element) -> V.Storage
        where V.Index == Index3
    {
        let storage = V.Storage.init(elements: (
            unsafeBitCast(fn(.i0), to: V.Storage.A.self),
            unsafeBitCast(fn(.i1), to: V.Storage.B.self),
            unsafeBitCast(fn(.i2), to: V.Storage.C.self),
            () as! V.Storage.D
        ))
        return storage
    }
    func getElement<V: Vector>(from vector: V) -> V.Element where V.Index
== Index3 {
        switch self {
        case .i0: return unsafeBitCast(vector.storage.elements.0, to:
V.Element.self)
        case .i1: return unsafeBitCast(vector.storage.elements.1, to:
V.Element.self)
        case .i2: return unsafeBitCast(vector.storage.elements.2, to:
V.Element.self)
        }
    }
    func setElement<V: Vector>(of vector: inout V, to value: V.Element)
where V.Index == Index3 {
        switch self {
        case .i0: vector.storage.elements.0 = unsafeBitCast(value, to:
V.Storage.A.self)
        case .i1: vector.storage.elements.1 = unsafeBitCast(value, to:
V.Storage.B.self)
        case .i2: vector.storage.elements.2 = unsafeBitCast(value, to:
V.Storage.C.self)
        }
    }
}
protocol Vector {
    associatedtype Index: VectorIndex
    associatedtype Element
    associatedtype Storage: VectorStorage
    var storage: Storage { get set }
    init(elementForIndex: (Index) -> Element)
}
extension Vector {
    subscript(index: Index) -> Element {
        get { return index.getElement(from: self) }
        set { index.setElement(of: &self, to: newValue) }
    }
    func map<NewElement>(transform: (Element) -> NewElement) -> SV32<Index,
NewElement> {
        return SV32<Index, NewElement> { index in transform(self[index]) }
    }
    func map<NewElement>(transform: (Element) -> NewElement) -> SV64<Index,
NewElement> {
        return SV64<Index, NewElement> { index in transform(self[index]) }
    }
}

protocol VectorElement {
    associatedtype BitPattern
}


extension UInt8 : VectorElement { typealias BitPattern = UInt8 }
extension UInt16 : VectorElement { typealias BitPattern = UInt16 }
extension UInt32 : VectorElement { typealias BitPattern = UInt32 }
extension UInt64 : VectorElement { typealias BitPattern = UInt64 }
extension Int : VectorElement { typealias BitPattern = UInt64 }
extension Double : VectorElement { typealias BitPattern = UInt64 }
extension Float : VectorElement { typealias BitPattern = UInt32 }


struct SV32<I: VectorIndex, E: VectorElement> : Vector where
    E.BitPattern == UInt32
{
    typealias Index = I
    typealias Element = E
    var storage: Index.StorageOf32BitElements
    init(elementForIndex: (Index) -> Element) {
        self.storage = Index.vectorStorage(for: SV32.self, from:
elementForIndex)
    }
}
struct SV64<I: VectorIndex, E: VectorElement> : Vector where
    E.BitPattern == UInt64
{
    typealias Index = I
    typealias Element = E
    var storage: Index.StorageOf64BitElements
    init(elementForIndex: (Index) -> Element) {
        self.storage = Index.vectorStorage(for: SV64.self, from:
elementForIndex)
    }
}

protocol DoubleConvertible {
    var double: Double { get }
}
extension Float : DoubleConvertible {
    var double: Double { return Double(self) }
}
extension Vector where Element: DoubleConvertible {
    var doubleVector: SV64<Index, Double> { return self.map { $0.double }  }
}
extension Vector {
    func casted<V: Vector>(to _: V.Type) -> V {
        fatalError()
    }
}

func test() {
    var v = SV32<Index3, Float> { _ in 0.0 }

    v[.i0] = 1.1
    v[.i1] = 2.2
    v[.i2] = 3.3

    let dv = v.doubleVector

    print(dv[.i0])
    print(dv[.i1])
    print(dv[.i2])
}
test()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170710/b80315c3/attachment.html>


More information about the swift-users mailing list