Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type)


(Benedikt Terhechte) #1

+ 1 For this. Subscriptable tuples would be awesome.

···

Rather than introduce a new kind of declaration, I think we could add a few small features to tuples:

- We could say the type (n * T) is equivalent to a homogeneous tuple of n elements, and
- We could allow tuples to be subscriptable, producing a value of the common supertype of its elements.

That would make the experience of working with imported C types a lot better.

-Joe

> On Jan 27, 2016, at 7:50 PM, Justin Kolb via swift-evolution<swift-evolution at swift.org>wrote:
>
> 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution