Skip to content

Commit

Permalink
Allow setproperty! for PointerWrappers with special structs (#79)
Browse files Browse the repository at this point in the history
* allow setproperty! for PointerWrappers with special structs

* Update pointerwrappers.jl
  • Loading branch information
JoshuaLampert authored Apr 16, 2023
1 parent f5bf0ad commit e3522da
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
7 changes: 4 additions & 3 deletions src/pointerwrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ end
function Base.setproperty!(pw::PointerWrapper{T}, name::Symbol, v) where T
i = findfirst(isequal(name), fieldnames(T))
if isnothing(i)
error("type $(string(T)) has no field $name")
# For some `struct`s, `fieldnames` gives `data` and not the actual field names, but we can use `Base.setproperty!` for pointers,
# see https://github.com/trixi-framework/P4est.jl/issues/72 and https://github.com/trixi-framework/P4est.jl/issues/79
return Base.setproperty!(pointer(pw), name, v)
end

unsafe_store!(reinterpret(Ptr{fieldtype(T, i)}, pointer(pw) + fieldoffset(T, i)), v)
return unsafe_store!(reinterpret(Ptr{fieldtype(T, i)}, pointer(pw) + fieldoffset(T, i)), v)
end

# `[]` allows one to access the actual underlying data and
Expand Down
14 changes: 12 additions & 2 deletions test/tests_basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,22 @@ end
ptr = Base.unsafe_convert(Ptr{MyStruct}, Ref(obj))
pw = PointerWrapper(ptr)
@test pw.value[] == 0.0
pw.value[] = 1.0
@test_nowarn pw.value[] = 1.0
@test pw.value[] == 1.0
@test pw.value[1] == 1.0
pw.value[1] = 2.0
@test_nowarn pw.value[1] = 2.0
@test pw.value[1] == 2.0
@test pw.value[] == 2.0
# using `setproperty!`
@test_nowarn pw.value = 3.0
@test pw.value[1] == 3.0
@test pw.value[] == 3.0
# using `setproperty!` for special `struct`s
# see https://github.com/trixi-framework/P4est.jl/issues/72 and https://github.com/trixi-framework/P4est.jl/issues/79
@test p4est_pw.global_first_position.level[] == 29
@test_nowarn p4est_pw.global_first_position.level = 30
@test p4est_pw.global_first_position.level[] == 30
@test_nowarn p4est_pw.global_first_position.level = 29

# test if we can set the user_pointer
p4est_pw.user_pointer = Ptr{Cvoid}(3)
Expand Down

0 comments on commit e3522da

Please sign in to comment.