Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
change more convert methods to constructors
Browse files Browse the repository at this point in the history
deprecate a few more sketchy `convert` methods
JeffBezanson committed Aug 30, 2017
1 parent 5e038db commit fe19369
Showing 31 changed files with 208 additions and 188 deletions.
7 changes: 4 additions & 3 deletions base/Enums.jl
Original file line number Diff line number Diff line change
@@ -9,8 +9,9 @@ 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))
Integer(x::Enum{T}) where {T<:Integer} = bitcast(T, 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)))

@@ -106,7 +107,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
2 changes: 1 addition & 1 deletion base/asyncmap.jl
Original file line number Diff line number Diff line change
@@ -248,7 +248,7 @@ end
function asyncmap(f, s::AbstractString; kwargs...)
s2 = Array{Char,1}(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.
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

17 changes: 17 additions & 0 deletions base/boot.jl
Original file line number Diff line number Diff line change
@@ -610,4 +610,21 @@ Int(x::Ptr) = bitcast(Int, x)
UInt(x::Ptr) = bitcast(UInt, x)
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::Real) = Signed(x)::Integer

ccall(:jl_set_istopmod, Void, (Any, Bool), Core, true)
19 changes: 11 additions & 8 deletions base/c.jl
Original file line number Diff line number Diff line change
@@ -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{Void}}) = bitcast(Cstring, p)
Cwstring(p::Union{Ptr{Cwchar_t},Ptr{Void}}) = bitcast(Cwstring, p)
(::Type{Ptr{T}})(p::Cstring) where {T<:Union{Int8,UInt8,Void}} = bitcast(Ptr{T}, p)
(::Type{Ptr{T}})(p::Cwstring) where {T<:Union{Cwchar_t,Void}} = bitcast(Ptr{Cwchar_t}, p)

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

"""
pointer(array [, index])
@@ -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
"""
11 changes: 5 additions & 6 deletions base/complex.jl
Original file line number Diff line number Diff line change
@@ -32,13 +32,12 @@ const Complex128 = Complex{Float64}
const Complex64 = Complex{Float32}
const Complex32 = 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)}
13 changes: 13 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
@@ -1706,8 +1706,21 @@ export hex2num
@deprecate convert(::Type{Symbol}, s::AbstractString) Symbol(s)
@deprecate convert(::Type{String}, s::Symbol) String(s)
@deprecate convert(::Type{String}, v::Vector{UInt8}) String(v)
@deprecate convert(::Type{String}, v::AbstractVector{Char}) String(v)
@deprecate convert(::Type{S}, g::UTF8proc.GraphemeIterator) where {S<:AbstractString} convert(S, g.s)

@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 #5148, PR #23259
# warning for `const` on locals should be changed to an error in julia-syntax.scm

68 changes: 36 additions & 32 deletions base/float.jl
Original file line number Diff line number Diff line change
@@ -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
@@ -54,27 +54,28 @@ 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))
Integer(x::Float16) = Integer(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
@@ -88,7 +89,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
@@ -104,7 +105,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
@@ -118,7 +119,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
@@ -134,7 +135,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))
@@ -157,7 +158,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
@@ -235,33 +236,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)
@@ -675,11 +679,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
@@ -696,11 +700,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
36 changes: 18 additions & 18 deletions base/gmp.jl
Original file line number Diff line number Diff line change
@@ -228,7 +228,7 @@ widen(::Type{BigInt}) = BigInt

signed(x::BigInt) = x

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

hastypemax(::Type{BigInt}) = false

@@ -260,14 +260,14 @@ function tryparse_internal(::Type{BigInt}, s::AbstractString, startpos::Int, end
Nullable(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

@@ -276,10 +276,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))
@@ -321,26 +321,26 @@ function rem(x::BigInt, ::Type{T}) where T<:Union{Unsigned,Signed}
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<:Unsigned
function (::Type{T})(x::BigInt) where T<:Unsigned
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<:Signed
function (::Type{T})(x::BigInt) where T<:Signed
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
@@ -383,9 +383,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

Loading

0 comments on commit fe19369

Please sign in to comment.