<div dir="ltr">Oops sorry, I intended to send that code to myself but autocompletion made it go to swift-users ...<div>/Jens</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 10, 2017 at 7:46 PM, Jens Persson via swift-users <span dir="ltr"><<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><div dir="ltr">protocol VectorStorage {<br> associatedtype A<br> associatedtype B<br> associatedtype C<br> associatedtype D<br> var elements: (A, B, C, D) { get set }<br> init(elements: (A, B, C, D))<br>}<br>struct VectorStorage2<T> : VectorStorage {<br> var elements: (T, T, Void, Void)<br>}<br>struct VectorStorage3<T> : VectorStorage {<br> var elements: (T, T, T, Void)<br>}<br><br>protocol VectorIndex {<br> associatedtype StorageOf8BitElements: VectorStorage<br> associatedtype StorageOf16BitElements: VectorStorage<br> associatedtype StorageOf32BitElements: VectorStorage<br> associatedtype StorageOf64BitElements: VectorStorage<br> static func vectorStorage<V: Vector>(for: V.Type, from fn: (Self) -> V.Element) -> V.Storage<br> where V.Index == Self<br> func getElement<V: Vector>(from: V) -> V.Element where V.Index == Self<br> func setElement<V: Vector>(of vector: inout V, to value: V.Element) where V.Index == Self<br>}<br>enum Index2 : VectorIndex {<br> typealias StorageOf8BitElements = VectorStorage2<UInt8><br> typealias StorageOf16BitElements = VectorStorage2<UInt16><br> typealias StorageOf32BitElements = VectorStorage2<UInt32><br> typealias StorageOf64BitElements = VectorStorage2<UInt64><br> case i0, i1<br> static func vectorStorage<V: Vector>(for: V.Type, from fn: (Index2) -> V.Element) -> V.Storage<br> where V.Index == Index2<br> {<br> let storage = V.Storage.init(elements: (<br> unsafeBitCast(fn(.i0), to: V.Storage.A.self),<br> unsafeBitCast(fn(.i1), to: V.Storage.B.self),<br> () as! V.Storage.C,<br> () as! V.Storage.D<br> ))<br> return storage<br> }<br> func getElement<V: Vector>(from vector: V) -> V.Element where V.Index == Index2 {<br> switch self {<br> case .i0: return unsafeBitCast(vector.storage.<wbr>elements.0, to: V.Element.self)<br> case .i1: return unsafeBitCast(vector.storage.<wbr>elements.1, to: V.Element.self)<br> }<br> }<br> func setElement<V: Vector>(of vector: inout V, to value: V.Element) where V.Index == Index2 {<br> switch self {<br> case .i0: vector.storage.elements.0 = unsafeBitCast(value, to: V.Storage.A.self)<br> case .i1: vector.storage.elements.1 = unsafeBitCast(value, to: V.Storage.B.self)<br> }<br> }<br>}<br>enum Index3 : VectorIndex {<br> typealias StorageOf8BitElements = VectorStorage3<UInt8><br> typealias StorageOf16BitElements = VectorStorage3<UInt16><br> typealias StorageOf32BitElements = VectorStorage3<UInt32><br> typealias StorageOf64BitElements = VectorStorage3<UInt64><br> case i0, i1, i2<br> static func vectorStorage<V: Vector>(for: V.Type, from fn: (Index3) -> V.Element) -> V.Storage<br> where V.Index == Index3<br> {<br> let storage = V.Storage.init(elements: (<br> unsafeBitCast(fn(.i0), to: V.Storage.A.self),<br> unsafeBitCast(fn(.i1), to: V.Storage.B.self),<br> unsafeBitCast(fn(.i2), to: V.Storage.C.self),<br> () as! V.Storage.D<br> ))<br> return storage<br> }<br> func getElement<V: Vector>(from vector: V) -> V.Element where V.Index == Index3 {<br> switch self {<br> case .i0: return unsafeBitCast(vector.storage.<wbr>elements.0, to: V.Element.self)<br> case .i1: return unsafeBitCast(vector.storage.<wbr>elements.1, to: V.Element.self)<br> case .i2: return unsafeBitCast(vector.storage.<wbr>elements.2, to: V.Element.self)<br> }<br> }<br> func setElement<V: Vector>(of vector: inout V, to value: V.Element) where V.Index == Index3 {<br> switch self {<br> case .i0: vector.storage.elements.0 = unsafeBitCast(value, to: V.Storage.A.self)<br> case .i1: vector.storage.elements.1 = unsafeBitCast(value, to: V.Storage.B.self)<br> case .i2: vector.storage.elements.2 = unsafeBitCast(value, to: V.Storage.C.self)<br> }<br> }<br>}<br>protocol Vector {<br> associatedtype Index: VectorIndex<br> associatedtype Element<br> associatedtype Storage: VectorStorage<br> var storage: Storage { get set }<br> init(elementForIndex: (Index) -> Element)<br>}<br>extension Vector {<br> subscript(index: Index) -> Element {<br> get { return index.getElement(from: self) }<br> set { index.setElement(of: &self, to: newValue) }<br> }<br> func map<NewElement>(transform: (Element) -> NewElement) -> SV32<Index, NewElement> {<br> return SV32<Index, NewElement> { index in transform(self[index]) }<br> }<br> func map<NewElement>(transform: (Element) -> NewElement) -> SV64<Index, NewElement> {<br> return SV64<Index, NewElement> { index in transform(self[index]) }<br> }<br>}<br><br>protocol VectorElement {<br> associatedtype BitPattern<br>}<br><br><br>extension UInt8 : VectorElement { typealias BitPattern = UInt8 }<br>extension UInt16 : VectorElement { typealias BitPattern = UInt16 }<br>extension UInt32 : VectorElement { typealias BitPattern = UInt32 }<br>extension UInt64 : VectorElement { typealias BitPattern = UInt64 }<br>extension Int : VectorElement { typealias BitPattern = UInt64 }<br>extension Double : VectorElement { typealias BitPattern = UInt64 }<br>extension Float : VectorElement { typealias BitPattern = UInt32 }<br><br><br>struct SV32<I: VectorIndex, E: VectorElement> : Vector where<br> E.BitPattern == UInt32<br>{<br> typealias Index = I<br> typealias Element = E<br> var storage: Index.StorageOf32BitElements<br> init(elementForIndex: (Index) -> Element) {<br> self.storage = Index.vectorStorage(for: SV32.self, from: elementForIndex)<br> }<br>}<br>struct SV64<I: VectorIndex, E: VectorElement> : Vector where<br> E.BitPattern == UInt64<br>{<br> typealias Index = I<br> typealias Element = E<br> var storage: Index.StorageOf64BitElements<br> init(elementForIndex: (Index) -> Element) {<br> self.storage = Index.vectorStorage(for: SV64.self, from: elementForIndex)<br> }<br>}<br><br>protocol DoubleConvertible {<br> var double: Double { get }<br>}<br>extension Float : DoubleConvertible {<br> var double: Double { return Double(self) }<br>}<br>extension Vector where Element: DoubleConvertible {<br> var doubleVector: SV64<Index, Double> { return self.map { $0.double } }<br>}<br>extension Vector {<br> func casted<V: Vector>(to _: V.Type) -> V {<br> fatalError()<br> }<br>}<br><br>func test() {<br> var v = SV32<Index3, Float> { _ in 0.0 }<br> <br> v[.i0] = 1.1<br> v[.i1] = 2.2<br> v[.i2] = 3.3<br> <br> let dv = v.doubleVector<br> <br> print(dv[.i0])<br> print(dv[.i1])<br> print(dv[.i2])<br>}<br>test()</div>
</div></div><br>______________________________<wbr>_________________<br>
swift-users mailing list<br>
<a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br>
<br></blockquote></div><br></div>