3

If I have a struct like

struct Point4D
{
    let x:Double, 
        y:Double, 
        z:Double, 
        w:Double
}

is there an efficient way to access the members of the struct by integer index? Meaning

let index:Int = 2
let point:Point4D = Point4D(x: 1, y: 5, z: 3, w: 8)
let component:Double = point [index] // 3

I suppose this is possible by defining the subscript() method on Point4D and using a switch statement but this doesn’t seem very efficient. In C I believe you can increment a pointer to the first struct member since they are all of type Double, but Swift doesn’t allow this…

1
  • 2
    You would be better off defining a four-element array, and providing four calculated properties to access its elements. Commented Mar 27, 2017 at 0:01

2 Answers 2

0

Think what you are asking for in the context of Swift, a strongly (primarily) statically typed language.

What would the type of the nth member of a struct be where n is not known till compile time?

(Note that in referencing tuples elements, e.g. (1, true, 3.4).1 -> true, the selector is a literal value and not variable so the type is always known.)

The Swift designers could have chosen to include a special case for structures all of whose elements are the same type, but that would probably be rather confusing.

You should consider your design and why you need this operation and named access to components. If it is important consider a custom type with appropriate operations, maybe based on an array for storage.

Sign up to request clarification or add additional context in comments.

2 Comments

Indexed access is needed in this part of the code because I am performing dot products, but since the target vectors are parallel to the axes of the coordinate system, doing full dot products is wasteful when you could just grab the component you want. Named access is used everywhere else so using Array as a data structure would be awkward.
You don't need indexed access to perform a dot product, and with only 4-elements vectors it isnt clear it's a win. However if you wish to support it consider a custom type which uses an array internally and provides appropriate operations as suggested - say both individual properties for each element and indexed operations. HTH
0

Here's one approach to get the value of a component. It should be efficient. It'd be interesting to performance test against the subscript/switch alternative to see the speed difference.

func componentValue(_ pointer: UnsafePointer<Point4D>, at index: Int) -> Double {
    return pointer.withMemoryRebound(to: Double.self, capacity: 4) { ptr -> Double in
        return (ptr+index).pointee
    }
}

struct Point4D
{
    let x:Double,
    y:Double,
    z:Double,
    w:Double
}

let index:Int = 2
var point:Point4D = Point4D(x: 1, y: 5, z: 3, w: 8)
let component:Double = componentValue(&point, at: index)    // 3

1 Comment

And if the members have different types?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.