Reinterpret UInt64 as SVector{8,UInt8}

I’d like to reinterpret a UInt64 as a SVector{8, UInt8}:

julia> reinterpret(SVector{8, UInt8}, UInt64(1235189))
ERROR: bitcast: target type not a leaf primitive type
Stacktrace:
 [1] reinterpret(::Type{SArray{Tuple{8},UInt8,1,8}}, ::UInt64) at ./essentials.jl:381
 [2] top-level scope at none:0

It’s not working the other way round either:

julia> reinterpret(UInt64, SVector{8, UInt8}(1,1,1,1,1,1,1,1))
Error showing value of type Base.ReinterpretArray{UInt64,1,UInt8,SArray{Tuple{8},UInt8,1,8}}:
ERROR: MethodError: no method matching SOneTo{8}(::UnitRange{Int64})

Is there something that I am missing?

reinterpret for non-primitive types works only on Arrays, so this works:

julia> reinterpret(SVector{8, UInt8}, [UInt64(1235189)])
1-element reinterpret(SArray{Tuple{8},UInt8,1,8}, ::Array{UInt64,1}):
 [0xf5, 0xd8, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00]

For further reading the are some issues about this: Extend reinterpret to immutable isbits() type · Issue #13701 · JuliaLang/julia · GitHub Reinterpret immutables · Issue #10140 · JuliaLang/julia · GitHub

1 Like
julia> using StaticArrays
julia> function force_reinterpret(dst_typ, src)
       M=MVector(src)
       GC.@preserve M begin 
       p = convert(Ptr{dst_typ}, pointer_from_objref(M))
       return unsafe_load(p)
       end
       end
julia> t = SVector{8, UInt8}; u=rand(UInt)
0x7789306ff6a51882
julia> force_reinterpret(t, u)
8-element SArray{Tuple{8},UInt8,1,8}:
 0x82
 0x18
 0xa5
 0xf6
 0x6f
 0x30
 0x89
 0x77

No allocation, but @code_native is nevertheless disgusting. Same kind of disgusting as @code_native getindex(reinterpret(t, [u]),1), which is the perennial issue of the new ReinterpretArray: Bytes are loaded one by one.

2 Likes