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