Skip to content

Commit

Permalink
change more convert methods to constructors
Browse files Browse the repository at this point in the history
deprecate a few more sketchy `convert` methods
  • Loading branch information
JeffBezanson committed Dec 21, 2017
1 parent 97e7c0c commit 0e726e6
Show file tree
Hide file tree
Showing 30 changed files with 199 additions and 189 deletions.
6 changes: 3 additions & 3 deletions base/Enums.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ function basetype end

abstract type Enum{T<:Integer} end

Base.convert(::Type{Integer}, x::Enum{T}) where {T<:Integer} = bitcast(T, x)
Base.convert(::Type{T}, x::Enum{T2}) where {T<:Integer,T2<:Integer} = convert(T, bitcast(T2, x))
(::Type{T})(x::Enum{T2}) where {T<:Integer,T2<:Integer} = T(bitcast(T2, x))::T
Base.cconvert(::Type{T}, x::Enum{T2}) where {T<:Integer,T2<:Integer} = T(x)
Base.write(io::IO, x::Enum{T}) where {T<:Integer} = write(io, T(x))
Base.read(io::IO, ::Type{T}) where {T<:Enum} = T(read(io, Enums.basetype(T)))

Expand Down Expand Up @@ -106,7 +106,7 @@ macro enum(T, syms...)
blk = quote
# enum definition
Base.@__doc__(primitive type $(esc(typename)) <: Enum{$(basetype)} $(sizeof(basetype) * 8) end)
function Base.convert(::Type{$(esc(typename))}, x::Integer)
function $(esc(typename))(x::Integer)
$(membershiptest(:x, values)) || enum_argument_error($(Expr(:quote, typename)), x)
return bitcast($(esc(typename)), convert($(basetype), x))
end
Expand Down
2 changes: 1 addition & 1 deletion base/asyncmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ end
function asyncmap(f, s::AbstractString; kwargs...)
s2 = Vector{Char}(uninitialized, length(s))
asyncmap!(f, s2, s; kwargs...)
return convert(String, s2)
return String(s2)
end

# map on a single BitArray returns a BitArray if the mapping function is boolean.
Expand Down
6 changes: 0 additions & 6 deletions base/bool.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

## boolean conversions ##

convert(::Type{Bool}, x::Bool) = x
convert(::Type{Bool}, x::Float16) = x==0 ? false : x==1 ? true : throw(InexactError(:convert, Bool, x))
convert(::Type{Bool}, x::Real) = x==0 ? false : x==1 ? true : throw(InexactError(:convert, Bool, x))

# promote Bool to any other numeric type
promote_rule(::Type{Bool}, ::Type{T}) where {T<:Number} = T

Expand Down
17 changes: 17 additions & 0 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -687,4 +687,21 @@ UInt64(x::Ptr) = UInt64(UInt32(x))
end
Ptr{T}(x::Union{Int,UInt,Ptr}) where {T} = bitcast(Ptr{T}, x)

Signed(x::UInt8) = Int8(x)
Unsigned(x::Int8) = UInt8(x)
Signed(x::UInt16) = Int16(x)
Unsigned(x::Int16) = UInt16(x)
Signed(x::UInt32) = Int32(x)
Unsigned(x::Int32) = UInt32(x)
Signed(x::UInt64) = Int64(x)
Unsigned(x::Int64) = UInt64(x)
Signed(x::UInt128) = Int128(x)
Unsigned(x::Int128) = UInt128(x)

Signed(x::Union{Float32, Float64, Bool}) = Int(x)
Unsigned(x::Union{Float32, Float64, Bool}) = UInt(x)

Integer(x::Integer) = x
Integer(x::Union{Float32, Float64}) = Int(x)

ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Core, true)
19 changes: 11 additions & 8 deletions base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,16 @@ Cwchar_t
end
end

# construction from typed pointers
convert(::Type{Cstring}, p::Ptr{<:Union{Int8,UInt8}}) = bitcast(Cstring, p)
convert(::Type{Cwstring}, p::Ptr{Cwchar_t}) = bitcast(Cwstring, p)
convert(::Type{Ptr{T}}, p::Cstring) where {T<:Union{Int8,UInt8}} = bitcast(Ptr{T}, p)
convert(::Type{Ptr{Cwchar_t}}, p::Cwstring) = bitcast(Ptr{Cwchar_t}, p)
# construction from pointers
Cstring(p::Union{Ptr{Int8},Ptr{UInt8},Ptr{Cvoid}}) = bitcast(Cstring, p)
Cwstring(p::Union{Ptr{Cwchar_t},Ptr{Cvoid}}) = bitcast(Cwstring, p)
(::Type{Ptr{T}})(p::Cstring) where {T<:Union{Int8,UInt8,Cvoid}} = bitcast(Ptr{T}, p)
(::Type{Ptr{T}})(p::Cwstring) where {T<:Union{Cwchar_t,Cvoid}} = bitcast(Ptr{Cwchar_t}, p)

# construction from untyped pointers
convert(::Type{T}, p::Ptr{Cvoid}) where {T<:Union{Cstring,Cwstring}} = bitcast(T, p)
convert(::Type{Cstring}, p::Union{Ptr{Int8},Ptr{UInt8},Ptr{Cvoid}}) = Cstring(p)
convert(::Type{Cwstring}, p::Union{Ptr{Cwchar_t},Ptr{Cvoid}}) = Cwstring(p)
convert(::Type{Ptr{T}}, p::Cstring) where {T<:Union{Int8,UInt8,Cvoid}} = Ptr{T}(p)
convert(::Type{Ptr{T}}, p::Cwstring) where {T<:Union{Cwchar_t,Cvoid}} = Ptr{T}(p)

"""
pointer(array [, index])
Expand Down Expand Up @@ -157,7 +159,8 @@ function unsafe_convert(::Type{Cwstring}, v::Vector{Cwchar_t})
end

# symbols are guaranteed not to contain embedded NUL
convert(::Type{Cstring}, s::Symbol) = Cstring(unsafe_convert(Ptr{Cchar}, s))
cconvert(::Type{Cstring}, s::Symbol) = s
unsafe_convert(::Type{Cstring}, s::Symbol) = Cstring(unsafe_convert(Ptr{Cchar}, s))

@static if ccall(:jl_get_UNAME, Any, ()) === :NT
"""
Expand Down
11 changes: 5 additions & 6 deletions base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ const ComplexF64 = Complex{Float64}
const ComplexF32 = Complex{Float32}
const ComplexF16 = Complex{Float16}

convert(::Type{Complex{T}}, x::Real) where {T<:Real} = Complex{T}(x,0)
convert(::Type{Complex{T}}, z::Complex) where {T<:Real} = Complex{T}(real(z),imag(z))
convert(::Type{T}, z::Complex) where {T<:Real} =
isreal(z) ? convert(T,real(z)) : throw(InexactError(:convert, T, z))
Complex{T}(x::Real) where {T<:Real} = Complex{T}(x,0)
Complex{T}(z::Complex) where {T<:Real} = Complex{T}(real(z),imag(z))
(::Type{T})(z::Complex) where {T<:Real} =
isreal(z) ? T(real(z))::T : throw(InexactError(Symbol(string(T)), T, z))

convert(::Type{Complex}, z::Complex) = z
convert(::Type{Complex}, x::Real) = Complex(x)
Complex(z::Complex) = z

promote_rule(::Type{Complex{T}}, ::Type{S}) where {T<:Real,S<:Real} =
Complex{promote_type(T,S)}
Expand Down
13 changes: 13 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,19 @@ export hex2num
@deprecate convert(::Type{String}, s::Symbol) String(s)
@deprecate convert(::Type{String}, v::Vector{UInt8}) String(v)
@deprecate convert(::Type{S}, g::Unicode.GraphemeIterator) where {S<:AbstractString} convert(S, g.s)
@deprecate convert(::Type{String}, v::AbstractVector{Char}) String(v)

@deprecate convert(::Type{UInt128}, u::Random.UUID) UInt128(u)
@deprecate convert(::Type{Random.UUID}, s::AbstractString) Random.UUID(s)
@deprecate convert(::Type{Libc.FILE}, s::IO) Libc.FILE(s)
@deprecate convert(::Type{VersionNumber}, v::Integer) VersionNumber(v)
@deprecate convert(::Type{VersionNumber}, v::Tuple) VersionNumber(v)
@deprecate convert(::Type{VersionNumber}, v::AbstractString) VersionNumber(v)

@deprecate (convert(::Type{Integer}, x::Enum{T}) where {T<:Integer}) Integer(x)
@deprecate (convert(::Type{T}, x::Enum{T2}) where {T<:Integer,T2<:Integer}) T(x)

@deprecate convert(dt::Type{<:Integer}, ip::IPAddr) dt(ip)

# Issue #19923
@deprecate ror circshift
Expand Down
67 changes: 35 additions & 32 deletions base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ A not-a-number value of type [`Float64`](@ref).
const NaN = NaN64

## conversions to floating-point ##
convert(::Type{Float16}, x::Integer) = convert(Float16, convert(Float32, x))
Float16(x::Integer) = convert(Float16, convert(Float32, x))
for t in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128)
@eval promote_rule(::Type{Float16}, ::Type{$t}) = Float16
end
Expand All @@ -54,27 +54,27 @@ promote_rule(::Type{Float16}, ::Type{Bool}) = Float16
for t1 in (Float32, Float64)
for st in (Int8, Int16, Int32, Int64)
@eval begin
convert(::Type{$t1}, x::($st)) = sitofp($t1, x)
(::Type{$t1})(x::($st)) = sitofp($t1, x)
promote_rule(::Type{$t1}, ::Type{$st}) = $t1
end
end
for ut in (Bool, UInt8, UInt16, UInt32, UInt64)
@eval begin
convert(::Type{$t1}, x::($ut)) = uitofp($t1, x)
(::Type{$t1})(x::($ut)) = uitofp($t1, x)
promote_rule(::Type{$t1}, ::Type{$ut}) = $t1
end
end
end
convert(::Type{Integer}, x::Float16) = convert(Integer, Float32(x))
convert(::Type{T}, x::Float16) where {T<:Integer} = convert(T, Float32(x))
(::Type{T})(x::Float16) where {T<:Integer} = T(Float32(x))

Bool(x::Real) = x==0 ? false : x==1 ? true : throw(InexactError(:Bool, Bool, x))

promote_rule(::Type{Float64}, ::Type{UInt128}) = Float64
promote_rule(::Type{Float64}, ::Type{Int128}) = Float64
promote_rule(::Type{Float32}, ::Type{UInt128}) = Float32
promote_rule(::Type{Float32}, ::Type{Int128}) = Float32

function convert(::Type{Float64}, x::UInt128)
function Float64(x::UInt128)
x == 0 && return 0.0
n = 128-leading_zeros(x) # ndigits0z(x,2)
if n <= 53
Expand All @@ -88,7 +88,7 @@ function convert(::Type{Float64}, x::UInt128)
reinterpret(Float64, d + y)
end

function convert(::Type{Float64}, x::Int128)
function Float64(x::Int128)
x == 0 && return 0.0
s = ((x >>> 64) % UInt64) & 0x8000_0000_0000_0000 # sign bit
x = abs(x) % UInt128
Expand All @@ -104,7 +104,7 @@ function convert(::Type{Float64}, x::Int128)
reinterpret(Float64, s | d + y)
end

function convert(::Type{Float32}, x::UInt128)
function Float32(x::UInt128)
x == 0 && return 0f0
n = 128-leading_zeros(x) # ndigits0z(x,2)
if n <= 24
Expand All @@ -118,7 +118,7 @@ function convert(::Type{Float32}, x::UInt128)
reinterpret(Float32, d + y)
end

function convert(::Type{Float32}, x::Int128)
function Float32(x::Int128)
x == 0 && return 0f0
s = ((x >>> 96) % UInt32) & 0x8000_0000 # sign bit
x = abs(x) % UInt128
Expand All @@ -134,7 +134,7 @@ function convert(::Type{Float32}, x::Int128)
reinterpret(Float32, s | d + y)
end

function convert(::Type{Float16}, val::Float32)
function Float16(val::Float32)
f = reinterpret(UInt32, val)
if isnan(val)
t = 0x8000 (0x8000 & ((f >> 0x10) % UInt16))
Expand All @@ -157,7 +157,7 @@ function convert(::Type{Float16}, val::Float32)
reinterpret(Float16, h)
end

function convert(::Type{Float32}, val::Float16)
function Float32(val::Float16)
local ival::UInt32 = reinterpret(UInt16, val)
local sign::UInt32 = (ival & 0x8000) >> 15
local exp::UInt32 = (ival & 0x7c00) >> 10
Expand Down Expand Up @@ -235,33 +235,36 @@ for i = 0:255
shifttable[i|0x100+1] = 13
end
end

#convert(::Type{Float16}, x::Float32) = fptrunc(Float16, x)
convert(::Type{Float32}, x::Float64) = fptrunc(Float32, x)
convert(::Type{Float16}, x::Float64) = convert(Float16, convert(Float32, x))
Float32(x::Float64) = fptrunc(Float32, x)
Float16(x::Float64) = Float16(Float32(x))

#convert(::Type{Float32}, x::Float16) = fpext(Float32, x)
convert(::Type{Float64}, x::Float32) = fpext(Float64, x)
convert(::Type{Float64}, x::Float16) = convert(Float64, convert(Float32, x))

convert(::Type{AbstractFloat}, x::Bool) = convert(Float64, x)
convert(::Type{AbstractFloat}, x::Int8) = convert(Float64, x)
convert(::Type{AbstractFloat}, x::Int16) = convert(Float64, x)
convert(::Type{AbstractFloat}, x::Int32) = convert(Float64, x)
convert(::Type{AbstractFloat}, x::Int64) = convert(Float64, x) # LOSSY
convert(::Type{AbstractFloat}, x::Int128) = convert(Float64, x) # LOSSY
convert(::Type{AbstractFloat}, x::UInt8) = convert(Float64, x)
convert(::Type{AbstractFloat}, x::UInt16) = convert(Float64, x)
convert(::Type{AbstractFloat}, x::UInt32) = convert(Float64, x)
convert(::Type{AbstractFloat}, x::UInt64) = convert(Float64, x) # LOSSY
convert(::Type{AbstractFloat}, x::UInt128) = convert(Float64, x) # LOSSY
Float64(x::Float32) = fpext(Float64, x)
Float64(x::Float16) = Float64(Float32(x))

AbstractFloat(x::Bool) = Float64(x)
AbstractFloat(x::Int8) = Float64(x)
AbstractFloat(x::Int16) = Float64(x)
AbstractFloat(x::Int32) = Float64(x)
AbstractFloat(x::Int64) = Float64(x) # LOSSY
AbstractFloat(x::Int128) = Float64(x) # LOSSY
AbstractFloat(x::UInt8) = Float64(x)
AbstractFloat(x::UInt16) = Float64(x)
AbstractFloat(x::UInt32) = Float64(x)
AbstractFloat(x::UInt64) = Float64(x) # LOSSY
AbstractFloat(x::UInt128) = Float64(x) # LOSSY

Bool(x::Float16) = x==0 ? false : x==1 ? true : throw(InexactError(:Bool, Bool, x))

"""
float(x)
Convert a number or array to a floating point data type.
When passed a string, this function is equivalent to `parse(Float64, x)`.
"""
float(x) = convert(AbstractFloat, x)
float(x) = AbstractFloat(x)

"""
float(T::Type)
Expand Down Expand Up @@ -675,11 +678,11 @@ for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UIn
throw(InexactError(:trunc, $Ti, x))
end
end
function convert(::Type{$Ti}, x::$Tf)
function (::Type{$Ti})(x::$Tf)
if ($(Tf(typemin(Ti))) <= x <= $(Tf(typemax(Ti)))) && (trunc(x) == x)
return unsafe_trunc($Ti,x)
else
throw(InexactError(:convert, $Ti, x))
throw(InexactError($(Expr(:quote,Ti.name.name)), $Ti, x))
end
end
end
Expand All @@ -696,11 +699,11 @@ for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UIn
throw(InexactError(:trunc, $Ti, x))
end
end
function convert(::Type{$Ti}, x::$Tf)
function (::Type{$Ti})(x::$Tf)
if ($(Tf(typemin(Ti))) <= x < $(Tf(typemax(Ti)))) && (trunc(x) == x)
return unsafe_trunc($Ti,x)
else
throw(InexactError(:convert, $Ti, x))
throw(InexactError($(Expr(:quote,Ti.name.name)), $Ti, x))
end
end
end
Expand Down
38 changes: 19 additions & 19 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ widen(::Type{BigInt}) = BigInt

signed(x::BigInt) = x

convert(::Type{BigInt}, x::BigInt) = x
convert(::Type{Signed}, x::BigInt) = x
BigInt(x::BigInt) = x
Signed(x::BigInt) = x

hastypemax(::Type{BigInt}) = false

Expand Down Expand Up @@ -262,14 +262,14 @@ function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, end
flipsign!(z, sgn)
end

convert(::Type{BigInt}, x::Union{Clong,Int32}) = MPZ.set_si(x)
convert(::Type{BigInt}, x::Union{Culong,UInt32}) = MPZ.set_ui(x)
convert(::Type{BigInt}, x::Bool) = BigInt(UInt(x))
BigInt(x::Union{Clong,Int32}) = MPZ.set_si(x)
BigInt(x::Union{Culong,UInt32}) = MPZ.set_ui(x)
BigInt(x::Bool) = BigInt(UInt(x))

unsafe_trunc(::Type{BigInt}, x::Union{Float32,Float64}) = MPZ.set_d(x)

function convert(::Type{BigInt}, x::Union{Float32,Float64})
isinteger(x) || throw(InexactError(:convert, BigInt, x))
function BigInt(x::Union{Float32,Float64})
isinteger(x) || throw(InexactError(:BigInt, BigInt, x))
unsafe_trunc(BigInt,x)
end

Expand All @@ -278,10 +278,10 @@ function trunc(::Type{BigInt}, x::Union{Float32,Float64})
unsafe_trunc(BigInt,x)
end

convert(::Type{BigInt}, x::Float16) = BigInt(Float64(x))
convert(::Type{BigInt}, x::Float32) = BigInt(Float64(x))
BigInt(x::Float16) = BigInt(Float64(x))
BigInt(x::Float32) = BigInt(Float64(x))

function convert(::Type{BigInt}, x::Integer)
function BigInt(x::Integer)
if x < 0
if typemin(Clong) <= x
return BigInt(convert(Clong,x))
Expand Down Expand Up @@ -323,26 +323,26 @@ function rem(x::BigInt, ::Type{T}) where T<:Union{Base.BitUnsigned,Base.BitSigne
flipsign(u, x.size)
end

rem(x::Integer, ::Type{BigInt}) = convert(BigInt, x)
rem(x::Integer, ::Type{BigInt}) = BigInt(x)

function convert(::Type{T}, x::BigInt) where T<:Base.BitUnsigned
function (::Type{T})(x::BigInt) where T<:Base.BitUnsigned
if sizeof(T) < sizeof(Limb)
convert(T, convert(Limb,x))
else
0 <= x.size <= cld(sizeof(T),sizeof(Limb)) || throw(InexactError(:convert, T, x))
0 <= x.size <= cld(sizeof(T),sizeof(Limb)) || throw(InexactError(Symbol(string(T)), T, x))
x % T
end
end

function convert(::Type{T}, x::BigInt) where T<:Base.BitSigned
function (::Type{T})(x::BigInt) where T<:Base.BitSigned
n = abs(x.size)
if sizeof(T) < sizeof(Limb)
SLimb = typeof(Signed(one(Limb)))
convert(T, convert(SLimb, x))
else
0 <= n <= cld(sizeof(T),sizeof(Limb)) || throw(InexactError(:convert, T, x))
0 <= n <= cld(sizeof(T),sizeof(Limb)) || throw(InexactError(Symbol(string(T)), T, x))
y = x % T
ispos(x) (y > 0) && throw(InexactError(:convert, T, x)) # catch overflow
ispos(x) (y > 0) && throw(InexactError(Symbol(string(T)), T, x)) # catch overflow
y
end
end
Expand Down Expand Up @@ -385,9 +385,9 @@ function (::Type{T})(n::BigInt, ::RoundingMode{:Nearest}) where T<:CdoubleMax
x
end

convert(::Type{Float64}, n::BigInt) = Float64(n,RoundNearest)
convert(::Type{Float32}, n::BigInt) = Float32(n,RoundNearest)
convert(::Type{Float16}, n::BigInt) = Float16(n,RoundNearest)
Float64(n::BigInt) = Float64(n, RoundNearest)
Float32(n::BigInt) = Float32(n, RoundNearest)
Float16(n::BigInt) = Float16(n, RoundNearest)

promote_rule(::Type{BigInt}, ::Type{<:Integer}) = BigInt

Expand Down
Loading

0 comments on commit 0e726e6

Please sign in to comment.