Skip to content

Commit

Permalink
Merge pull request #69 from aplavin/master
Browse files Browse the repository at this point in the history
add intervalsets and staticarrays support
  • Loading branch information
jw3126 authored Feb 17, 2023
2 parents c703441 + 5d04874 commit 4d661f8
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 2 deletions.
16 changes: 14 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
name = "ConstructionBase"
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
authors = ["Takafumi Arakaki", "Rafael Schouten", "Jan Weidner"]
version = "1.4.1"
version = "1.5.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[weakdeps]
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"

[extensions]
IntervalSetsExt = "IntervalSets"
StaticArraysExt = "StaticArrays"

[compat]
IntervalSets = "0.5, 0.6, 0.7"
StaticArrays = "1"
julia = "1"

[extras]
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
test = ["IntervalSets","StaticArrays","Test"]
8 changes: 8 additions & 0 deletions ext/IntervalSetsExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module IntervalSetsExt

using ConstructionBase
using IntervalSets

ConstructionBase.constructorof(::Type{<:Interval{L, R}}) where {L, R} = Interval{L, R}

end
31 changes: 31 additions & 0 deletions ext/StaticArraysExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module StaticArraysExt

using ConstructionBase
using StaticArrays

# general static arrays need to keep the size parameter
ConstructionBase.constructorof(sa::Type{<:SArray{S}}) where {S} = SArray{S}
ConstructionBase.constructorof(sa::Type{<:MArray{S}}) where {S} = MArray{S}
ConstructionBase.constructorof(sa::Type{<:SizedArray{S}}) where {S} = SizedArray{S}

# static vectors don't even need the explicit size specification
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
N <= 4 || error("type $obj does not have properties $(join(KS, ", "))")
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
46 changes: 46 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,49 @@ end
@inferred getproperties(funny_numbers(S,20))
@inferred getproperties(funny_numbers(S,40))
end


using StaticArrays, IntervalSets

if isdefined(Base, :get_extension) # some 1.9 version
@testset "staticarrays" begin
sa = @SVector [2, 4, 6, 8]
sa2 = ConstructionBase.constructorof(typeof(sa))((3.0, 5.0, 7.0, 9.0))
@test sa2 === @SVector [3.0, 5.0, 7.0, 9.0]

ma = @MMatrix [2.0 4.0; 6.0 8.0]
ma2 = @inferred ConstructionBase.constructorof(typeof(ma))((1, 2, 3, 4))
@test ma2 isa MArray{Tuple{2,2},Int,2,4}
@test all(ma2 .=== @MMatrix [1 3; 2 4])

sz = SizedArray{Tuple{2,2}}([1 2;3 4])
sz2 = @inferred ConstructionBase.constructorof(typeof(sz))([:a :b; :c :d])
@test sz2 == SizedArray{Tuple{2,2}}([:a :b; :c :d])
@test typeof(sz2) <: SizedArray{Tuple{2,2},Symbol,2,2}

for T in (SVector, MVector)
@test @inferred(ConstructionBase.constructorof(T)((1, 2, 3)))::T == T((1, 2, 3))
@test @inferred(ConstructionBase.constructorof(T{3})((1, 2, 3)))::T == T((1, 2, 3))
@test @inferred(ConstructionBase.constructorof(T{3})((1, 2)))::T == T((1, 2))
@test @inferred(ConstructionBase.constructorof(T{3, Symbol})((1, 2, 3)))::T == T((1, 2, 3))
@test @inferred(ConstructionBase.constructorof(T{3, Symbol})((1, 2)))::T == T((1, 2))
@test @inferred(ConstructionBase.constructorof(T{3, X} where {X})((1, 2, 3)))::T == T((1, 2, 3))
@test @inferred(ConstructionBase.constructorof(T{3, X} where {X})((1, 2)))::T == T((1, 2))
@test @inferred(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)
@test_throws "does not have properties z" setproperties(SVector(1, 2, 3, 4, 5), z = 3.0)
end

@testset "intervalsets" begin
@test constructorof(typeof(1..2))(0.5, 1.5) === 0.5..1.5
@test constructorof(typeof(OpenInterval(1, 2)))(0.5, 1.5) === OpenInterval(0.5, 1.5)
@test setproperties(1..2, left=0.0) === 0.0..2.0
@test setproperties(OpenInterval(1.0, 2.0), left=1, right=5) === OpenInterval(1, 5)
end
end

0 comments on commit 4d661f8

Please sign in to comment.