[swift-users] komihåg swift 4 Vector

Jens Persson jens at bitcycle.com
Mon Jul 10 12:49:05 CDT 2017


Oops sorry, I intended to send that code to myself but autocompletion made
it go to swift-users ...
/Jens

On Mon, Jul 10, 2017 at 7:46 PM, Jens Persson via swift-users <
swift-users at swift.org> wrote:

> 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()
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170710/592ea0e9/attachment.html>


More information about the swift-users mailing list