[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