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@swift.org https://lists.swift.org/mailman/listinfo/swift-users