Skip to content

Commit 1ddedc8

Browse files
authored
PseudoPtr (#3)
* Impliment PseudoPtr * More test coverage and version bump
1 parent 4ce7d92 commit 1ddedc8

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ManualMemory"
22
uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667"
33
authors = ["chriselrod <[email protected]> and contributors"]
4-
version = "0.1.3"
4+
version = "0.1.4"
55

66
[compat]
77
julia = "1.5"

src/ManualMemory.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@ end
1010
@inline Base.unsafe_convert(::Type{Ptr{T}}, m::MemoryBuffer) where {T} = Ptr{T}(pointer_from_objref(m))
1111
@inline Base.pointer(m::MemoryBuffer{N,T}) where {N,T} = Ptr{T}(pointer_from_objref(m))
1212

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)))
1330
@generated function load(p::Ptr{T}) where {T}
1431
if Base.allocatedinline(T)
1532
Expr(:block, Expr(:meta,:inline), :(unsafe_load(p)))
@@ -18,6 +35,10 @@ end
1835
end
1936
end
2037
@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
2142
@generated function store!(p::Ptr{T}, v::T) where {T}
2243
if Base.allocatedinline(T)
2344
Expr(:block, Expr(:meta,:inline), :(unsafe_store!(p, v); return nothing))

test/runtests.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using ManualMemory: MemoryBuffer, load, store!, LazyPreserve, preserve
1+
using ManualMemory: MemoryBuffer, load, store!, LazyPreserve, preserve, PseudoPtr
22
using Test
33

44
@testset "ManualMemory.jl" begin
@@ -16,6 +16,14 @@ using Test
1616
x = [0 0; 0 0];
1717
preserve(store!, LazyPreserve(x), 1)
1818
@test x[1] === 1
19+
p = PseudoPtr(x, 1)
20+
@test load(p) === 1
21+
p += 1
22+
store!(p, 2)
23+
@test load(p) === 2
24+
p = 1 + p
25+
store!(p, 3)
26+
@test load(p) === 3
1927
end
2028

2129
using ThreadingUtilities

0 commit comments

Comments
 (0)