Skip to content

Commit

Permalink
support named properties of staticvectors
Browse files Browse the repository at this point in the history
  • Loading branch information
aplavin committed Jan 26, 2023
1 parent 65dcf63 commit 72e3ce6
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
15 changes: 15 additions & 0 deletions ext/StaticArraysExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,19 @@ ConstructionBase.constructorof(sa::Type{<:SizedArray{S}}) where {S} = SizedArray
ConstructionBase.constructorof(::Type{<:SVector}) = SVector
ConstructionBase.constructorof(::Type{<:MVector}) = MVector

# set properties by name: x, y, z, w
@generated function ConstructionBase.setproperties(obj::Union{SVector{N}, MVector{N}}, patch::NamedTuple{KS}) where {N, KS}
if KS == (:data,)
:( constructorof(typeof(obj))(only(patch)) )
else
propnames = (:x, :y, :z, :w)[1:N]
KS propnames || error("type $obj does not have properties $(join(KS, ", "))")
field_exprs = map(enumerate(propnames)) do (i, p)
from = p KS ? :patch : :obj
:( $from.$p )
end
:( constructorof(typeof(obj))($(field_exprs...)) )
end
end

end
7 changes: 7 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,13 @@ if isdefined(Base, :get_extension) # some 1.9 version
@test ConstructionBase.constructorof(T{3, X} where {X})((1, 2))::T == T((1, 2))
@test ConstructionBase.constructorof(T{X, Symbol} where {X})((1, 2, 3))::T == T((1, 2, 3))
end

sv = SVector(1, 2)
@test SVector(3.0, 2.0) === @inferred setproperties(sv, x = 3.0)
@test SVector(3.0, 5.0) === @inferred setproperties(sv, x = 3.0, y = 5.0)
@test SVector(-1.0, -2.0) === @inferred setproperties(sv, data = (-1.0, -2))

@test_throws "does not have properties z" setproperties(sv, z = 3.0)
end

@testset "intervalsets" begin
Expand Down

0 comments on commit 72e3ce6

Please sign in to comment.