fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
This commit is contained in:
124
julia-0.6.3/share/julia/base/refpointer.jl
Normal file
124
julia-0.6.3/share/julia/base/refpointer.jl
Normal file
@@ -0,0 +1,124 @@
|
||||
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
||||
|
||||
"""
|
||||
Ref{T}
|
||||
|
||||
An object that safely references data of type `T`. This type is guaranteed to point to
|
||||
valid, Julia-allocated memory of the correct type. The underlying data is protected from
|
||||
freeing by the garbage collector as long as the `Ref` itself is referenced.
|
||||
|
||||
When passed as a `ccall` argument (either as a `Ptr` or `Ref` type), a `Ref` object will be
|
||||
converted to a native pointer to the data it references.
|
||||
|
||||
There is no invalid (NULL) `Ref`.
|
||||
"""
|
||||
Ref
|
||||
|
||||
# C NUL-terminated string pointers; these can be used in ccall
|
||||
# instead of Ptr{Cchar} and Ptr{Cwchar_t}, respectively, to enforce
|
||||
# a check for embedded NUL chars in the string (to avoid silent truncation).
|
||||
if Int === Int64
|
||||
primitive type Cstring 64 end
|
||||
primitive type Cwstring 64 end
|
||||
else
|
||||
primitive type Cstring 32 end
|
||||
primitive type Cwstring 32 end
|
||||
end
|
||||
|
||||
### General Methods for Ref{T} type
|
||||
|
||||
eltype(x::Type{Ref{T}}) where {T} = T
|
||||
convert(::Type{Ref{T}}, x::Ref{T}) where {T} = x
|
||||
|
||||
# create Ref objects for general object conversion
|
||||
unsafe_convert(::Type{Ref{T}}, x::Ref{T}) where {T} = unsafe_convert(Ptr{T}, x)
|
||||
unsafe_convert(::Type{Ref{T}}, x) where {T} = unsafe_convert(Ptr{T}, x)
|
||||
|
||||
### Methods for a Ref object that can store a single value of any type
|
||||
|
||||
mutable struct RefValue{T} <: Ref{T}
|
||||
x::T
|
||||
RefValue{T}() where {T} = new()
|
||||
RefValue{T}(x) where {T} = new(x)
|
||||
end
|
||||
RefValue(x::T) where {T} = RefValue{T}(x)
|
||||
isassigned(x::RefValue) = isdefined(x, :x)
|
||||
|
||||
Ref(x::Ref) = x
|
||||
Ref(x::Any) = RefValue(x)
|
||||
Ref(x::Ptr{T}, i::Integer=1) where {T} = x + (i-1)*Core.sizeof(T)
|
||||
Ref(x, i::Integer) = (i != 1 && error("Object only has one element"); Ref(x))
|
||||
Ref{T}() where {T} = RefValue{T}() # Ref{T}()
|
||||
Ref{T}(x) where {T} = RefValue{T}(x) # Ref{T}(x)
|
||||
convert(::Type{Ref{T}}, x) where {T} = RefValue{T}(x)
|
||||
|
||||
function unsafe_convert(P::Type{Ptr{T}}, b::RefValue{T}) where T
|
||||
if isbits(T)
|
||||
return convert(P, data_pointer_from_objref(b))
|
||||
else
|
||||
return convert(P, data_pointer_from_objref(b.x))
|
||||
end
|
||||
end
|
||||
function unsafe_convert(P::Type{Ptr{Any}}, b::RefValue{Any})
|
||||
return convert(P, data_pointer_from_objref(b))
|
||||
end
|
||||
unsafe_convert(::Type{Ptr{Void}}, b::RefValue{T}) where {T} = convert(Ptr{Void}, unsafe_convert(Ptr{T}, b))
|
||||
|
||||
### Methods for a Ref object that is backed by an array at index i
|
||||
struct RefArray{T,A<:AbstractArray{T},R} <: Ref{T}
|
||||
x::A
|
||||
i::Int
|
||||
roots::R # should be either ::Void or ::Any
|
||||
RefArray{T,A,R}(x,i,roots=nothing) where {T,A<:AbstractArray{T},R} = new(x,i,roots)
|
||||
end
|
||||
RefArray(x::AbstractArray{T}, i::Int, roots::Any) where {T} = RefArray{T,typeof(x),Any}(x, i, roots)
|
||||
RefArray(x::AbstractArray{T}, i::Int=1, roots::Void=nothing) where {T} = RefArray{T,typeof(x),Void}(x, i, nothing)
|
||||
convert(::Type{Ref{T}}, x::AbstractArray{T}) where {T} = RefArray(x, 1)
|
||||
Ref(x::AbstractArray, i::Integer=1) = RefArray(x, i)
|
||||
|
||||
function unsafe_convert(P::Type{Ptr{T}}, b::RefArray{T}) where T
|
||||
if isbits(T)
|
||||
convert(P, pointer(b.x, b.i))
|
||||
else
|
||||
convert(P, data_pointer_from_objref(b.x[b.i]))
|
||||
end
|
||||
end
|
||||
function unsafe_convert(P::Type{Ptr{Any}}, b::RefArray{Any})
|
||||
return convert(P, pointer(b.x, b.i))
|
||||
end
|
||||
unsafe_convert(::Type{Ptr{Void}}, b::RefArray{T}) where {T} = convert(Ptr{Void}, unsafe_convert(Ptr{T}, b))
|
||||
|
||||
# convert Arrays to pointer arrays for ccall
|
||||
function Ref{P}(a::Array{<:Union{Ptr,Cwstring,Cstring}}) where P<:Union{Ptr,Cwstring,Cstring}
|
||||
return RefArray(a) # effectively a no-op
|
||||
end
|
||||
function Ref{P}(a::Array{T}) where P<:Union{Ptr,Cwstring,Cstring} where T
|
||||
if (!isbits(T) && T <: eltype(P))
|
||||
# this Array already has the right memory layout for the requested Ref
|
||||
return RefArray(a,1,false) # root something, so that this function is type-stable
|
||||
else
|
||||
ptrs = Vector{P}(length(a)+1)
|
||||
roots = Vector{Any}(length(a))
|
||||
for i = 1:length(a)
|
||||
root = cconvert(P, a[i])
|
||||
ptrs[i] = unsafe_convert(P, root)::P
|
||||
roots[i] = root
|
||||
end
|
||||
ptrs[length(a)+1] = C_NULL
|
||||
return RefArray(ptrs,1,roots)
|
||||
end
|
||||
end
|
||||
cconvert(::Type{Ptr{P}}, a::Array{<:Ptr}) where {P<:Ptr} = a
|
||||
cconvert(::Type{Ref{P}}, a::Array{<:Ptr}) where {P<:Ptr} = a
|
||||
cconvert(::Type{Ptr{P}}, a::Array) where {P<:Union{Ptr,Cwstring,Cstring}} = Ref{P}(a)
|
||||
cconvert(::Type{Ref{P}}, a::Array) where {P<:Union{Ptr,Cwstring,Cstring}} = Ref{P}(a)
|
||||
|
||||
###
|
||||
|
||||
getindex(b::RefValue) = b.x
|
||||
getindex(b::RefArray) = b.x[b.i]
|
||||
|
||||
setindex!(b::RefValue, x) = (b.x = x; b)
|
||||
setindex!(b::RefArray, x) = (b.x[b.i] = x; b)
|
||||
|
||||
###
|
||||
Reference in New Issue
Block a user