|
10 | 10 | @inline Base.unsafe_convert(::Type{Ptr{T}}, m::MemoryBuffer) where {T} = Ptr{T}(pointer_from_objref(m))
|
11 | 11 | @inline Base.pointer(m::MemoryBuffer{N,T}) where {N,T} = Ptr{T}(pointer_from_objref(m))
|
12 | 12 |
|
| 13 | +""" |
| 14 | + PseudoPtr(data, position=firstindex(data)) |
| 15 | +
|
| 16 | +Provides a convenient wrapper that functions like `pointer(data)` for instances where `data` |
| 17 | +cannot produce a viable pointer. |
| 18 | +""" |
| 19 | +struct PseudoPtr{T,D} <: Ref{T} |
| 20 | + data::D |
| 21 | + position::Int |
| 22 | + |
| 23 | + PseudoPtr(data::D, position) where {D} = new{eltype(D),D}(data, position) |
| 24 | + PseudoPtr(data) = PseudoPtr(data, firstindex(data)) |
| 25 | +end |
| 26 | +Base.:(+)(x::PseudoPtr, y::Int) = PseudoPtr(getfield(x, :data), getfield(x, :position) + y) |
| 27 | +Base.:(+)(x::Int, y::PseudoPtr) = y + x |
| 28 | + |
| 29 | +@inline load(x::PseudoPtr) = @inbounds(getindex(getfield(x, :data), getfield(x, :position))) |
13 | 30 | @generated function load(p::Ptr{T}) where {T}
|
14 | 31 | if Base.allocatedinline(T)
|
15 | 32 | Expr(:block, Expr(:meta,:inline), :(unsafe_load(p)))
|
|
18 | 35 | end
|
19 | 36 | end
|
20 | 37 | @inline load(p::Ptr{UInt}, ::Type{T}) where {T} = load(p, T, 0)[2]
|
| 38 | + |
| 39 | +@inline function store!(x::PseudoPtr, val) |
| 40 | + @inbounds(setindex!(getfield(x, :data), val, getfield(x, :position))) |
| 41 | +end |
21 | 42 | @generated function store!(p::Ptr{T}, v::T) where {T}
|
22 | 43 | if Base.allocatedinline(T)
|
23 | 44 | Expr(:block, Expr(:meta,:inline), :(unsafe_store!(p, v); return nothing))
|
|
0 commit comments