# Reinterpret Tuple as Struct, and vector thereof

**URL:** <https://discourse.julialang.org/t/reinterpret-tuple-as-struct-and-vector-thereof/52324>\
**Category:** New to Julia\
**Created:** [December 24, 2020, 10:51am UTC](https://discourse.julialang.org/t/reinterpret-tuple-as-struct-and-vector-thereof/52324 "2020-12-24T10:51:46Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![circonflexe](https://avatars.discourse-cdn.com/v4/letter/c/c57346/32.png) [@circonflexe](https://discourse.julialang.org/u/circonflexe)\
**Post date:** [December 24, 2020, 10:51am UTC](https://discourse.julialang.org/t/reinterpret-tuple-as-struct-and-vector-thereof/52324/1 "2020-12-24T10:51:46Z")

</div>

So I am playing a bit with the [`Clipper.jl`](https://github.com/JuliaGeometry/Clipper.jl) library, which uses a type `IntPoint` defined as a struct of two `Int64` fields. However, it would be more convenient for me to use static vectors of fixed-point reals, i.e. `SVector{2,Fixed{64,F}} where{F}` (let’s call this type `T`); namely, `T` will support linear algebra, conversion to/from floats, et.c

So I am trying to convert data of type `Vector{T}` to `Vector{IntPoint}`, for passing to the `Clipper.jl` functions (which is a set of wrappers to a C library), without copying the objects (The fact that the `IntPoint` data are used in `ccall`, and that `SVector` holds its data in a tuple, guarantees that casting pointers around is safe). For a single `T` object I can do this in the following way:

```
Base.reinterpret(::Type{Clipper.IntPoint}, pt::SVector{2,Fixed{Int64}}) =
  unsafe_load(reinterpret(Ptr{Clipper.IntPoint}, pointer_from_objref(Ref(pt))))

```

(yes I used to program in C, but a pointer cast seems appropriate here since we are passing this to `ccall` anyway).

However I am unable to find a way to do this with a `Vector{T}` instead; my obvious attempt (inserting `Vector{}` everywhere in the above example) failed with `"pointerref: invalid pointer type"` (which, I imagine, is due to the difference between a C array and a Julia vector), while calling `vec2 = reinterpret(IntPoint, vec1)` does return a `Vector{IntPoint}`, but seems to make a copy (I checked that `pointer_from_objref(Ref(vec2[1]))` is different from `pointer_from_objref(Ref(vec1[1]))`).

What would be the best way to perform such an in-place reinterpretation?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 24, 2020, 12:55pm UTC](https://discourse.julialang.org/t/reinterpret-tuple-as-struct-and-vector-thereof/52324/2 "2020-12-24T12:55:15Z")

</div>

I will not answer directly your question, but maybe provide some useful information. Although the mutations of the elements of an array of immutable structs change the pointers, that happens in the stack, thus this is very fast and does not “allocate”. Thus, if you vector is of elements of one or other type, the elements can be mutated without allocating:

```julia
julia> struct IntPoint
         x :: Int64
         y :: Int64
       end

julia> v = Union{IntPoint,SVector{2,Int64}}[IntPoint(1,1)]
1-element Array{Union{IntPoint, SArray{Tuple{2},Int64,1,2}},1}:
 IntPoint(1, 1)

julia> function mutate!(v)
          v[1] = IntPoint(2,2)
          nothing
       end
mutate! (generic function with 1 method)

julia> @btime mutate!(v)
  10.767 ns (0 allocations: 0 bytes)

julia> function mutate2!(v)
          v[1] = SVector{2,Int64}(3,3)
          nothing
       end
mutate2! (generic function with 1 method)

julia> @btime mutate2!(v)
  11.043 ns (0 allocations: 0 bytes)

julia>

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 24, 2020, 2:05pm UTC](https://discourse.julialang.org/t/reinterpret-tuple-as-struct-and-vector-thereof/52324/3 "2020-12-24T14:05:13Z")

</div>

> [@circonflexe](#):
>
> So I am trying to convert data of type `Vector{T}` to `Vector{IntPoint}` , for passing to the `Clipper.jl` functions

This works, for example:

```julia
julia> a = rand(SVector{2,Int}, 10);

julia> b = reinterpret(IntPoint, a);

```

and no messing around with unsafe pointer operations.

The result is a `Base.ReinterpretArray{IntPoint, 1}`, which is a subtype of `AbstractVector{IntPoint}`. Unfortunately, the Clipper.jl library currently [only supports `Vector`](https://github.com/JuliaGeometry/Clipper.jl/issues/41). One way around this would be to do:

```julia
julia> v = unsafe_wrap(Array, pointer(b), length(b))

```

to get a `v` of type `Vector{IntPoint}`. Be sure to wrap `GC.@protect b begin ... end` around any code that needs to use `v`, to ensure that the underlying array doesn’t get garbage-collected while you are using it.
