diff --git a/src/pointerwrappers.jl b/src/pointerwrappers.jl index 3ee9457..57a15d7 100644 --- a/src/pointerwrappers.jl +++ b/src/pointerwrappers.jl @@ -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 diff --git a/test/tests_basic.jl b/test/tests_basic.jl index 0ec5a3f..fff81be 100644 --- a/test/tests_basic.jl +++ b/test/tests_basic.jl @@ -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)