The Completing Generics Manifesto suggests a more universal solution with generic value parameters which is my vote: Generic value parameters
Currently, Swift’s generic parameters are always types. One could imagine allowing generic parameters that are values, e.g., struct MultiArray<T, let Dimensions: Int> { // specify the number of dimensions to the array subscript (indices: Int...) -> T { get { require(indices.count == Dimensions) // ... } } A suitably general feature might allow us to express fixed-length array or vector types as a standard library component, and perhaps also allow one to implement a useful dimensional analysis library. Tackling this feature potentially means determining what it is for an expression to be a “constant expression” and diving into dependent-typing, hence the “maybe”. > To better support interfacing with lower level systems, like graphics > libraries for example, it would be helpful to support the concept of > contiguous variables. The most common use case for this would be to create > a Matrix struct that can be passed as data into something like Metal. This > can be accomplished now, using something like the following: > > Current Option 1: > > struct Matrix2x2 { > var m00: Float > var m01: Float > var m10: Float > var m11: Float > } > > OR > Current Option 2: > > struct Matrix2x2 { > var m: (Float, Float, Float, Float) > } > > OR > Current Option 3: > > struct Matrix2x2 { > var m: [Float] > } > > Options 1&2 allow for the compiler to enforce the fixed number of > elements and also for the data to be easily passed into graphics libraries > as their memory layout is somewhat predictable using sizeof, strideof, and > alignof. The downside is that you lose the ability to easily subscript or > iterate the elements. > > Option 3 does allow subscripting and iteration, but does not at compile > time enforce a fixed number of elements and is not as easily passed into a > library that expects to receive the raw data of the matrix. > > > Contiguous Variables: > > struct Matrix2x2 { > var m: Float:2*2 > } > > The variable `m` represents a series of 4 contiguous Float values. The > specific number of values must be a compile time constant. The only needed > functionality includes `count`, `subscript`, and iteration. To make things > easier to implement and to help avoid confusion and more complex > documentation, multiple dimensions are not allowed. To define multiple > dimensions you must provide your own ordering by wrapping this type in > another type and providing a custom subscript implementation. For example: > > struct RowMajorMatrix2x2 { > var m: Float:2*2 > > static let rows = 2 > static let columns = 2 > > subscript(row: Int, column: Int) ->Float { > return m[column * Matrix2x2.rows + row] > } > } > > sizeof(Matrix2x2) is 16 > strideof(Matrix2x2) is 16 > > m.count is essentially a compile time constant and is not stored with the > rest of the data but is available and can also be used to do runtime bounds > checking. > > struct Vector3 { > var v: Float:3 > } > > sizeof(Vector3) is 12 > strideof(Vector3) is 12 > > C code should also now be able to expose data types that contain fixed > sized arrays within them. > > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution