Open
Description
Motivation
SIMD
has subscripts available for accessing components at various indices. This offers some of the standard swizzling capabilities that you'd find in a shading language like Metal, but not enough to be considered fully-featured. This makes working with vectors cumbersome in Swift.
Metal:
float3 vector = {1, 2, 3};
vector.xy;
vector.xy = {4, 5};
Swift:
var vector: SIMD3<Float> = [1, 2, 3]
vector[[0, 1] as SIMD2] // ✅
vector[[0, 1]] = [4, 5] // ❌ Cannot assign through subscript: subscript is get-only
Proposed solution
- Add set accessors to the existing subscripts.
- Also, add defaults, to make assigning to the early parts of a vector especially easy.
- Add overloads for using indices directly, instead of having to pass in SIMDs.
vector[0, 2]
is better thanvector[[0, 2]]
.
That would replace and add to the following, which we can use presently:
// TODO: Use macros to support all SIMD types.
public extension SIMD where Scalar: SIMDScalar {
/// The ".xy" of a vector.
///
/// - Note: Acts as a default for the subscript that accesses elements based on a `SIMD2<Index>`,
/// and adds write capability to it.
subscript(index0: Int = 0, index1: Int = 1) -> SIMD2<Scalar> {
get { self[[index0, index1]] }
set {
for index in [index0, index1].indexed() {
self[index.element] = newValue[index.index]
}
}
}
/// The ".xyz" of a vector.
///
/// - Note: Acts as a default for the subscript that accesses elements based on a `SIMD3<Index>`,
/// and adds write capability to it.
subscript(index0: Int = 0, index1: Int = 1, index2: Int = 2) -> SIMD3<Scalar> {
get { self[[index0, index1, index2]] }
set {
for index in [index0, index1, index2].indexed() {
self[index.element] = newValue[index.index]
}
}
}
}
var double3 = SIMD3((10...12).map(Double.init))
var double4 = SIMD4((1...4).map(Double.init))
XCTAssertEqual(double3[], [10, 11] as SIMD2)
XCTAssertEqual(double4[], [1, 2, 3] as SIMD3)
double4[] += double3
XCTAssertEqual(double4, [11, 13, 15, 4])
double3[] += [0, 1] as SIMD2
XCTAssertEqual(double3, [10, 12, 12])
double3[1, 2] = [-1, -2]
XCTAssertEqual(double3, [10, -1, -2])