fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
This commit is contained in:
370
julia-0.6.3/share/julia/base/essentials.jl
Normal file
370
julia-0.6.3/share/julia/base/essentials.jl
Normal file
@@ -0,0 +1,370 @@
|
||||
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
||||
|
||||
using Core: CodeInfo
|
||||
|
||||
const Callable = Union{Function,Type}
|
||||
|
||||
const Bottom = Union{}
|
||||
|
||||
abstract type AbstractSet{T} end
|
||||
abstract type Associative{K,V} end
|
||||
|
||||
# The real @inline macro is not available until after array.jl, so this
|
||||
# internal macro splices the meta Expr directly into the function body.
|
||||
macro _inline_meta()
|
||||
Expr(:meta, :inline)
|
||||
end
|
||||
macro _noinline_meta()
|
||||
Expr(:meta, :noinline)
|
||||
end
|
||||
macro _pure_meta()
|
||||
Expr(:meta, :pure)
|
||||
end
|
||||
# another version of inlining that propagates an inbounds context
|
||||
macro _propagate_inbounds_meta()
|
||||
Expr(:meta, :inline, :propagate_inbounds)
|
||||
end
|
||||
|
||||
convert(::Type{Any}, x::ANY) = x
|
||||
convert(::Type{T}, x::T) where {T} = x
|
||||
|
||||
convert(::Type{Tuple{}}, ::Tuple{}) = ()
|
||||
convert(::Type{Tuple}, x::Tuple) = x
|
||||
convert(::Type{Tuple{Vararg{T}}}, x::Tuple) where {T} = cnvt_all(T, x...)
|
||||
cnvt_all(T) = ()
|
||||
cnvt_all(T, x, rest...) = tuple(convert(T,x), cnvt_all(T, rest...)...)
|
||||
|
||||
macro generated(f)
|
||||
if isa(f, Expr) && (f.head === :function || is_short_function_def(f))
|
||||
f.head = :stagedfunction
|
||||
return Expr(:escape, f)
|
||||
else
|
||||
error("invalid syntax; @generated must be used with a function definition")
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
@eval [mod,] ex
|
||||
|
||||
Evaluate an expression with values interpolated into it using `eval`.
|
||||
If two arguments are provided, the first is the module to evaluate in.
|
||||
"""
|
||||
macro eval(ex)
|
||||
:(eval($(current_module()), $(Expr(:quote,ex))))
|
||||
end
|
||||
macro eval(mod, ex)
|
||||
:(eval($(esc(mod)), $(Expr(:quote,ex))))
|
||||
end
|
||||
|
||||
argtail(x, rest...) = rest
|
||||
tail(x::Tuple) = argtail(x...)
|
||||
|
||||
tuple_type_head(T::UnionAll) = (@_pure_meta; UnionAll(T.var, tuple_type_head(T.body)))
|
||||
function tuple_type_head(T::DataType)
|
||||
@_pure_meta
|
||||
T.name === Tuple.name || throw(MethodError(tuple_type_head, (T,)))
|
||||
return unwrapva(T.parameters[1])
|
||||
end
|
||||
tuple_type_tail(T::UnionAll) = (@_pure_meta; UnionAll(T.var, tuple_type_tail(T.body)))
|
||||
function tuple_type_tail(T::DataType)
|
||||
@_pure_meta
|
||||
T.name === Tuple.name || throw(MethodError(tuple_type_tail, (T,)))
|
||||
if isvatuple(T) && length(T.parameters) == 1
|
||||
return T
|
||||
end
|
||||
return Tuple{argtail(T.parameters...)...}
|
||||
end
|
||||
|
||||
tuple_type_cons(::Type, ::Type{Union{}}) = Union{}
|
||||
function tuple_type_cons{S,T<:Tuple}(::Type{S}, ::Type{T})
|
||||
@_pure_meta
|
||||
Tuple{S, T.parameters...}
|
||||
end
|
||||
|
||||
function unwrap_unionall(a::ANY)
|
||||
while isa(a,UnionAll)
|
||||
a = a.body
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
function rewrap_unionall(t::ANY, u::ANY)
|
||||
if !isa(u, UnionAll)
|
||||
return t
|
||||
end
|
||||
return UnionAll(u.var, rewrap_unionall(t, u.body))
|
||||
end
|
||||
|
||||
# replace TypeVars in all enclosing UnionAlls with fresh TypeVars
|
||||
function rename_unionall(u::ANY)
|
||||
if !isa(u,UnionAll)
|
||||
return u
|
||||
end
|
||||
body = rename_unionall(u.body)
|
||||
if body === u.body
|
||||
body = u
|
||||
else
|
||||
body = UnionAll(u.var, body)
|
||||
end
|
||||
var = u.var::TypeVar
|
||||
nv = TypeVar(var.name, var.lb, var.ub)
|
||||
return UnionAll(nv, body{nv})
|
||||
end
|
||||
|
||||
const _va_typename = Vararg.body.body.name
|
||||
function isvarargtype(t::ANY)
|
||||
t = unwrap_unionall(t)
|
||||
isa(t, DataType) && (t::DataType).name === _va_typename
|
||||
end
|
||||
|
||||
isvatuple(t::DataType) = (n = length(t.parameters); n > 0 && isvarargtype(t.parameters[n]))
|
||||
function unwrapva(t::ANY)
|
||||
t2 = unwrap_unionall(t)
|
||||
isvarargtype(t2) ? t2.parameters[1] : t
|
||||
end
|
||||
|
||||
typename(a) = error("typename does not apply to this type")
|
||||
typename(a::DataType) = a.name
|
||||
function typename(a::Union)
|
||||
ta = typename(a.a)
|
||||
tb = typename(a.b)
|
||||
ta === tb ? tb : error("typename does not apply to unions whose components have different typenames")
|
||||
end
|
||||
typename(union::UnionAll) = typename(union.body)
|
||||
|
||||
convert(::Type{T}, x::Tuple{Any,Vararg{Any}}) where {T<:Tuple{Any,Vararg{Any}}} =
|
||||
tuple(convert(tuple_type_head(T),x[1]), convert(tuple_type_tail(T), tail(x))...)
|
||||
convert(::Type{T}, x::T) where {T<:Tuple{Any,Vararg{Any}}} = x
|
||||
|
||||
oftype(x,c) = convert(typeof(x),c)
|
||||
|
||||
unsigned(x::Int) = reinterpret(UInt, x)
|
||||
signed(x::UInt) = reinterpret(Int, x)
|
||||
|
||||
# conversions used by ccall
|
||||
ptr_arg_cconvert(::Type{Ptr{T}}, x) where {T} = cconvert(T, x)
|
||||
ptr_arg_unsafe_convert(::Type{Ptr{T}}, x) where {T} = unsafe_convert(T, x)
|
||||
ptr_arg_unsafe_convert(::Type{Ptr{Void}}, x) = x
|
||||
|
||||
cconvert(T::Type, x) = convert(T, x) # do the conversion eagerly in most cases
|
||||
cconvert(::Type{<:Ptr}, x) = x # but defer the conversion to Ptr to unsafe_convert
|
||||
unsafe_convert(::Type{T}, x::T) where {T} = x # unsafe_convert (like convert) defaults to assuming the convert occurred
|
||||
unsafe_convert(::Type{T}, x::T) where {T<:Ptr} = x # to resolve ambiguity with the next method
|
||||
unsafe_convert(::Type{P}, x::Ptr) where {P<:Ptr} = convert(P, x)
|
||||
|
||||
reinterpret(::Type{T}, x) where {T} = bitcast(T, x)
|
||||
reinterpret(::Type{Unsigned}, x::Float16) = reinterpret(UInt16,x)
|
||||
reinterpret(::Type{Signed}, x::Float16) = reinterpret(Int16,x)
|
||||
|
||||
sizeof(x) = Core.sizeof(x)
|
||||
|
||||
function append_any(xs...)
|
||||
# used by apply() and quote
|
||||
# must be a separate function from append(), since apply() needs this
|
||||
# exact function.
|
||||
out = Vector{Any}(4)
|
||||
l = 4
|
||||
i = 1
|
||||
for x in xs
|
||||
for y in x
|
||||
if i > l
|
||||
ccall(:jl_array_grow_end, Void, (Any, UInt), out, 16)
|
||||
l += 16
|
||||
end
|
||||
Core.arrayset(out, y, i)
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
ccall(:jl_array_del_end, Void, (Any, UInt), out, l-i+1)
|
||||
out
|
||||
end
|
||||
|
||||
# simple Array{Any} operations needed for bootstrap
|
||||
setindex!(A::Array{Any}, x::ANY, i::Int) = Core.arrayset(A, x, i)
|
||||
|
||||
function precompile(f::ANY, args::Tuple)
|
||||
ccall(:jl_compile_hint, Int32, (Any,), Tuple{Core.Typeof(f), args...}) != 0
|
||||
end
|
||||
|
||||
function precompile(argt::Type)
|
||||
ccall(:jl_compile_hint, Int32, (Any,), argt) != 0
|
||||
end
|
||||
|
||||
"""
|
||||
esc(e::ANY)
|
||||
|
||||
Only valid in the context of an `Expr` returned from a macro. Prevents the macro hygiene
|
||||
pass from turning embedded variables into gensym variables. See the [Macros](@ref man-macros)
|
||||
section of the Metaprogramming chapter of the manual for more details and examples.
|
||||
"""
|
||||
esc(e::ANY) = Expr(:escape, e)
|
||||
|
||||
macro boundscheck(blk)
|
||||
# hack: use this syntax since it avoids introducing line numbers
|
||||
:($(Expr(:boundscheck,true));
|
||||
$(esc(blk));
|
||||
$(Expr(:boundscheck,:pop)))
|
||||
end
|
||||
|
||||
"""
|
||||
@inbounds(blk)
|
||||
|
||||
Eliminates array bounds checking within expressions.
|
||||
|
||||
In the example below the bound check of array A is skipped to improve performance.
|
||||
|
||||
```julia
|
||||
function sum(A::AbstractArray)
|
||||
r = zero(eltype(A))
|
||||
for i = 1:length(A)
|
||||
@inbounds r += A[i]
|
||||
end
|
||||
return r
|
||||
end
|
||||
```
|
||||
|
||||
!!! warning
|
||||
|
||||
Using `@inbounds` may return incorrect results/crashes/corruption
|
||||
for out-of-bounds indices. The user is responsible for checking it manually.
|
||||
"""
|
||||
macro inbounds(blk)
|
||||
:($(Expr(:inbounds,true));
|
||||
$(esc(blk));
|
||||
$(Expr(:inbounds,:pop)))
|
||||
end
|
||||
|
||||
macro label(name::Symbol)
|
||||
Expr(:symboliclabel, name)
|
||||
end
|
||||
|
||||
macro goto(name::Symbol)
|
||||
Expr(:symbolicgoto, name)
|
||||
end
|
||||
|
||||
# SimpleVector
|
||||
|
||||
function getindex(v::SimpleVector, i::Int)
|
||||
if !(1 <= i <= length(v))
|
||||
throw(BoundsError(v,i))
|
||||
end
|
||||
x = unsafe_load(convert(Ptr{Ptr{Void}},data_pointer_from_objref(v)) + i*sizeof(Ptr))
|
||||
x == C_NULL && throw(UndefRefError())
|
||||
return unsafe_pointer_to_objref(x)
|
||||
end
|
||||
|
||||
length(v::SimpleVector) = v.length
|
||||
endof(v::SimpleVector) = v.length
|
||||
start(v::SimpleVector) = 1
|
||||
next(v::SimpleVector,i) = (v[i],i+1)
|
||||
done(v::SimpleVector,i) = (i > v.length)
|
||||
isempty(v::SimpleVector) = (v.length == 0)
|
||||
indices(v::SimpleVector) = (OneTo(length(v)),)
|
||||
linearindices(v::SimpleVector) = indices(v, 1)
|
||||
indices(v::SimpleVector, d) = d <= 1 ? indices(v)[d] : OneTo(1)
|
||||
|
||||
function ==(v1::SimpleVector, v2::SimpleVector)
|
||||
length(v1)==length(v2) || return false
|
||||
for i = 1:length(v1)
|
||||
v1[i] == v2[i] || return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
map(f, v::SimpleVector) = Any[ f(v[i]) for i = 1:length(v) ]
|
||||
|
||||
getindex(v::SimpleVector, I::AbstractArray) = Core.svec(Any[ v[i] for i in I ]...)
|
||||
|
||||
"""
|
||||
isassigned(array, i) -> Bool
|
||||
|
||||
Tests whether the given array has a value associated with index `i`. Returns `false`
|
||||
if the index is out of bounds, or has an undefined reference.
|
||||
|
||||
```jldoctest
|
||||
julia> isassigned(rand(3, 3), 5)
|
||||
true
|
||||
|
||||
julia> isassigned(rand(3, 3), 3 * 3 + 1)
|
||||
false
|
||||
|
||||
julia> mutable struct Foo end
|
||||
|
||||
julia> v = similar(rand(3), Foo)
|
||||
3-element Array{Foo,1}:
|
||||
#undef
|
||||
#undef
|
||||
#undef
|
||||
|
||||
julia> isassigned(v, 1)
|
||||
false
|
||||
```
|
||||
"""
|
||||
function isassigned end
|
||||
|
||||
function isassigned(v::SimpleVector, i::Int)
|
||||
1 <= i <= length(v) || return false
|
||||
x = unsafe_load(convert(Ptr{Ptr{Void}},data_pointer_from_objref(v)) + i*sizeof(Ptr))
|
||||
return x != C_NULL
|
||||
end
|
||||
|
||||
"""
|
||||
Colon()
|
||||
|
||||
Colons (:) are used to signify indexing entire objects or dimensions at once.
|
||||
|
||||
Very few operations are defined on Colons directly; instead they are converted
|
||||
by [`to_indices`](@ref) to an internal vector type (`Base.Slice`) to represent the
|
||||
collection of indices they span before being used.
|
||||
"""
|
||||
struct Colon
|
||||
end
|
||||
const (:) = Colon()
|
||||
|
||||
# For passing constants through type inference
|
||||
struct Val{T}
|
||||
end
|
||||
|
||||
# used by interpolating quote and some other things in the front end
|
||||
function vector_any(xs::ANY...)
|
||||
n = length(xs)
|
||||
a = Vector{Any}(n)
|
||||
@inbounds for i = 1:n
|
||||
Core.arrayset(a,xs[i],i)
|
||||
end
|
||||
a
|
||||
end
|
||||
|
||||
function as_kwargs(xs::Union{AbstractArray,Associative})
|
||||
n = length(xs)
|
||||
to = Vector{Any}(n*2)
|
||||
i = 1
|
||||
for (k, v) in xs
|
||||
to[i] = k::Symbol
|
||||
to[i+1] = v
|
||||
i += 2
|
||||
end
|
||||
return to
|
||||
end
|
||||
|
||||
function as_kwargs(xs)
|
||||
to = Vector{Any}(0)
|
||||
for (k, v) in xs
|
||||
ccall(:jl_array_ptr_1d_push2, Void, (Any, Any, Any), to, k::Symbol, v)
|
||||
end
|
||||
return to
|
||||
end
|
||||
|
||||
isempty(itr) = done(itr, start(itr))
|
||||
|
||||
"""
|
||||
invokelatest(f, args...)
|
||||
|
||||
Calls `f(args...)`, but guarantees that the most recent method of `f`
|
||||
will be executed. This is useful in specialized circumstances,
|
||||
e.g. long-running event loops or callback functions that may
|
||||
call obsolete versions of a function `f`.
|
||||
(The drawback is that `invokelatest` is somewhat slower than calling
|
||||
`f` directly, and the type of the result cannot be inferred by the compiler.)
|
||||
"""
|
||||
invokelatest(f, args...) = Core._apply_latest(f, args)
|
||||
Reference in New Issue
Block a user