Transmuting dynamic arrays and corresponding slices

An fixed array of f64’s on the form {x0, y0, x1, y1, …}
is equivalent to an array of structs like {{x0,y0},{x1,y1}…

So it’s easy to transmute between them:

    xyData := [?]f64{12.3, 23.4, 34.5, 45.6}
    ptType :: struct{ x,y : f64 }
    ptArray := transmute([len(xyData)/2]ptType)xyData 

But I cannot find a way to do the equivalent with dynamic arrays or slices. Tips?

In your example there’s not a single dynamic array…

[?]T is a fixed array for which the compiler figures out the size. Your transmute type is also a wanna be fixed array, with the exception that len() is runtime so that wouldn’t even work. Casts/transmutes needs types at compile time.

Afaik, this would work for fixed ones:

arr := [?]f32{0.0, 1.0, 2.0, 3.0}
S :: struct { x, y: f32 }
structs := transmute([size_of(arr) / size_of(S)]S)arr

For slices and dynamic arrays the easiest is to just make them into their raw type, recalculate the length (and capacity) and cast it to the new type.

slice := []f32{0.0, 1.0, 2.0, 3.0}
raw := transmute(runtime.Raw_Slice)slice
raw.len = len(slice)/2
structs := transmute([]S)raw

Raw_Slice

Well spotted! Exactly what the OP said :wink:

Sure, but if you don’t put the code you tried and didn’t work with an error message from the compiler or a print of what you expected to see, it just makes the person trying to help scratch his/her head trying to guess what you mean.

OP asked about slices and dynamic array transmute, but showed a fixed array which was also incorrectly transmuted. This begs the question if there’s a misunderstanding of what [?]T is even before we talk about slices and dynamic arrays.

Since, to my knowledge, Odin does not have a predefined type for a 2-dimensional point or vector, I wanted to declare a function that would receive an array of such data independent of how it was implemented in that program. The user may have defined his/her own point struct. But to circumvent the problem, I decided to instead receive data on the form [[x,y][x,y],[x,y],…]. Which should be easier to cast into, fram whatever type the user has declared.

There isn’t really any need for it, because arrays already behave like mathematical vectors:

And there’s a bunch of predefined stuff in linalg including 2D vector type aliases.

So far I really only seen 2 ways of people writing a point type in Odin:

Point :: [2]f32
Point :: distinct [2]f32

The first one just works with all the predefined maths in linalg, the second is if you want to force casting and be a little bit more type safe. Structs not really used because you’d need to implement everything that arrays already support.

1 Like