[swift-evolution] Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type)

Justin Kolb justin.kolb at gmail.com
Wed Jan 27 21:50:21 CST 2016


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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160127/68cd3767/attachment.html>


More information about the swift-evolution mailing list