Skip to content

Commit b99f251

Browse files
authored
Merge new reinterpret with essentials.jl reinterpret (#50367)
1 parent 930838b commit b99f251

File tree

4 files changed

+31
-43
lines changed

4 files changed

+31
-43
lines changed

base/essentials.jl

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -543,21 +543,41 @@ unsafe_convert(::Type{T}, x::T) where {T<:Ptr} = x # to resolve ambiguity with
543543
unsafe_convert(::Type{P}, x::Ptr) where {P<:Ptr} = convert(P, x)
544544

545545
"""
546-
reinterpret(type, x)
546+
reinterpret(::Type{Out}, x::In)
547547
548-
Change the type-interpretation of the binary data in the primitive value `x`
549-
to that of the primitive type `type`.
550-
The size of `type` has to be the same as that of the type of `x`.
548+
Change the type-interpretation of the binary data in the isbits value `x`
549+
to that of the isbits type `Out`.
550+
The size (ignoring padding) of `Out` has to be the same as that of the type of `x`.
551551
For example, `reinterpret(Float32, UInt32(7))` interprets the 4 bytes corresponding to `UInt32(7)` as a
552552
[`Float32`](@ref).
553553
554-
# Examples
555554
```jldoctest
556555
julia> reinterpret(Float32, UInt32(7))
557556
1.0f-44
557+
558+
julia> reinterpret(NTuple{2, UInt8}, 0x1234)
559+
(0x34, 0x12)
560+
561+
julia> reinterpret(UInt16, (0x34, 0x12))
562+
0x1234
563+
564+
julia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))
565+
(0x0301, 0x02)
558566
```
567+
568+
!!! warning
569+
570+
Use caution if some combinations of bits in `Out` are not considered valid and would
571+
otherwise be prevented by the type's constructors and methods. Unexpected behavior
572+
may result without additional validation.
559573
"""
560-
reinterpret(::Type{T}, x) where {T} = bitcast(T, x)
574+
function reinterpret(Out::Type, x::In) where {In}
575+
if isprimitivetype(Out) && isprimitivetype(In)
576+
return bitcast(Out, x)
577+
end
578+
# only available when Base is fully loaded.
579+
return _reinterpret(Out, x)
580+
end
561581

562582
"""
563583
sizeof(T::DataType)

base/reinterpretarray.jl

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -795,42 +795,10 @@ function _copyfrompacked!(ptr_out::Ptr{Out}, ptr_in::Ptr{In}) where {Out, In}
795795
end
796796
end
797797

798-
"""
799-
reinterpret(::Type{Out}, x::In)
800-
801-
Reinterpret the valid non-padding bytes of an isbits value `x` as isbits type `Out`.
802-
803-
Both types must have the same amount of non-padding bytes. This operation is guaranteed
804-
to be reversible.
805-
806-
```jldoctest
807-
julia> reinterpret(NTuple{2, UInt8}, 0x1234)
808-
(0x34, 0x12)
809-
810-
julia> reinterpret(UInt16, (0x34, 0x12))
811-
0x1234
812-
813-
julia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))
814-
(0x0301, 0x02)
815-
```
816-
817-
!!! warning
818-
819-
Use caution if some combinations of bits in `Out` are not considered valid and would
820-
otherwise be prevented by the type's constructors and methods. Unexpected behavior
821-
may result without additional validation.
822-
"""
823-
@inline function reinterpret(::Type{Out}, x::In) where {Out, In}
798+
@inline function _reinterpret(::Type{Out}, x::In) where {Out, In}
799+
# handle non-primitive types
824800
isbitstype(Out) || throw(ArgumentError("Target type for `reinterpret` must be isbits"))
825801
isbitstype(In) || throw(ArgumentError("Source type for `reinterpret` must be isbits"))
826-
if isprimitivetype(Out) && isprimitivetype(In)
827-
outsize = sizeof(Out)
828-
insize = sizeof(In)
829-
outsize == insize ||
830-
throw(ArgumentError("Sizes of types $Out and $In do not match; got $outsize \
831-
and $insize, respectively."))
832-
return bitcast(Out, x)
833-
end
834802
inpackedsize = packedsize(In)
835803
outpackedsize = packedsize(Out)
836804
inpackedsize == outpackedsize ||

test/core.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1897,7 +1897,7 @@ function f4528(A, B)
18971897
end
18981898
end
18991899
@test f4528(false, Int32(12)) === nothing
1900-
@test_throws ArgumentError f4528(true, Int32(12))
1900+
@test_throws ErrorException f4528(true, Int32(12))
19011901

19021902
# issue #4518
19031903
f4518(x, y::Union{Int32,Int64}) = 0

test/numbers.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,11 +2216,11 @@ end
22162216
@test round(Int16, -32768.1) === Int16(-32768)
22172217
end
22182218
# issue #7508
2219-
@test_throws ArgumentError reinterpret(Int, 0x01)
2219+
@test_throws ErrorException reinterpret(Int, 0x01)
22202220

22212221
@testset "issue #12832" begin
22222222
@test_throws ArgumentError reinterpret(Float64, Complex{Int64}(1))
2223-
@test_throws ArgumentError reinterpret(Int32, false)
2223+
@test_throws ErrorException reinterpret(Int32, false)
22242224
end
22252225
# issue #41
22262226
ndigf(n) = Float64(log(Float32(n)))

0 commit comments

Comments
 (0)