Skip to content

Commit 2a09e2c

Browse files
authored
Merge pull request #138 from JuliaArrays/sd/fixedsizearrays
bring back fixedsizearrays
2 parents 4d74ac7 + e1f68b1 commit 2a09e2c

File tree

7 files changed

+70
-52
lines changed

7 files changed

+70
-52
lines changed

src/FixedSizeArrays.jl

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,15 @@ end
8787

8888
macro fixed_vector(name, parent)
8989
esc(quote
90-
immutable $(name){S, T} <: $(parent){T}
90+
immutable $(name){S, T} <: $(parent){S, T}
9191
data::NTuple{S, T}
9292

93-
function $(name)(x::NTuple{S,T})
94-
new(x)
93+
function (::Type{$(name){S, T}}){S, T}(x::NTuple{S,T})
94+
new{S, T}(x)
9595
end
96-
function $(name)(x::NTuple{S})
97-
new(StaticArrays.convert_ntuple(T, x))
96+
97+
function (::Type{$(name){S, T}}){S, T}(x::NTuple{S,Any})
98+
new{S, T}(StaticArrays.convert_ntuple(T, x))
9899
end
99100
end
100101
# Array constructor
@@ -122,6 +123,19 @@ macro fixed_vector(name, parent)
122123
@inline function (::Type{$(name){S}}){S, T <: Tuple}(x::T)
123124
$(name){S, StaticArrays.promote_tuple_eltype(T)}(x)
124125
end
126+
(::Type{$(name){S, T}}){S, T}(x::StaticVector) = $(name){S, T}(Tuple(x))
127+
@generated function (::Type{$(name){S, T}}){S, T}(x::$(name))
128+
idx = [:(x[$i]) for i = 1:S]
129+
quote
130+
$($(name)){S, T}($(idx...))
131+
end
132+
end
133+
@generated function convert{S, T}(::Type{$(name){S, T}}, x::$(name))
134+
idx = [:(x[$i]) for i = 1:S]
135+
quote
136+
$($(name)){S, T}($(idx...))
137+
end
138+
end
125139
@generated function (::Type{SV}){SV <: $(name)}(x::StaticVector)
126140
len = size_or(SV, size(x))[1]
127141
if length(x) == len
@@ -134,36 +148,34 @@ macro fixed_vector(name, parent)
134148
end
135149
end
136150

137-
Base.@pure StaticArrays.Size{S}(::Type{$(name){S}}) = Size(S)
151+
Base.@pure StaticArrays.Size{S}(::Type{$(name){S, Any}}) = Size(S)
138152
Base.@pure StaticArrays.Size{S,T}(::Type{$(name){S, T}}) = Size(S)
139153

140-
Base.@propagate_inbounds function Base.getindex(v::$(name), i::Integer)
154+
Base.@propagate_inbounds function Base.getindex{S, T}(v::$(name){S, T}, i::Int)
141155
v.data[i]
142156
end
143157
@inline Base.Tuple(v::$(name)) = v.data
144158
@inline Base.convert{S, T}(::Type{$(name){S, T}}, x::NTuple{S, T}) = $(name){S, T}(x)
145-
@inline Base.convert{SV <: $(name)}(::Type{SV}, x::StaticVector) = SV(x)
159+
@inline Base.convert(::Type{$(name)}, x::StaticVector) = SV(x)
146160
@inline function Base.convert{S, T}(::Type{$(name){S, T}}, x::Tuple)
147161
$(name){S, T}(convert(NTuple{S, T}, x))
148162
end
149163

150-
@generated function StaticArrays.similar_type{SV <: $(name), T,S}(::Type{SV}, ::Type{T}, s::Size{S})
164+
@generated function StaticArrays.similar_type{SV <: $(name), T, S}(::Type{SV}, ::Type{T}, s::Size{S})
151165
if length(S) === 1
152166
$(name){S[1], T}
153167
else
154168
StaticArrays.default_similar_type(T,s(),Val{length(S)})
155169
end
156170
end
157-
158-
171+
size_or(::Type{$(name)}, or) = or
159172
eltype_or(::Type{$(name)}, or) = or
160-
eltype_or{T}(::Type{$(name){TypeVar(:S), T}}, or) = T
161-
eltype_or{S}(::Type{$(name){S, TypeVar(:T)}}, or) = or
173+
eltype_or{T}(::Type{$(name){S, T} where S}, or) = T
174+
eltype_or{S}(::Type{$(name){S, T} where T}, or) = or
162175
eltype_or{S, T}(::Type{$(name){S, T}}, or) = T
163176

164-
size_or(::Type{$(name)}, or) = or
165-
size_or{T}(::Type{$(name){TypeVar(:S), T}}, or) = or
166-
size_or{S}(::Type{$(name){S, TypeVar(:T)}}, or) = (S,)
177+
size_or{T}(::Type{$(name){S, T} where S}, or) = or
178+
size_or{S}(::Type{$(name){S, T} where T}, or) = Size{(S,)}()
167179
size_or{S, T}(::Type{$(name){S, T}}, or) = (S,)
168180
end)
169181
end

src/StaticArrays.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ include("eigen.jl")
9393
include("cholesky.jl")
9494
include("deque.jl")
9595

96-
#include("FixedSizeArrays.jl") # Currently defunct
96+
include("FixedSizeArrays.jl")
9797
include("ImmutableArrays.jl")
9898

9999
end # module

src/broadcast.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
_broadcast(f, broadcast_sizes(a...), a...)
99
end
1010

11+
@propagate_inbounds function broadcast{T}(f::Function, a::Type{T}, x::StaticArray)
12+
_broadcast(f, (Size(), Size(x)), T, x)
13+
end
14+
1115
@inline broadcast_sizes(a...) = _broadcast_sizes((), a...)
1216
@inline _broadcast_sizes(t::Tuple) = t
1317
@inline _broadcast_sizes(t::Tuple, a::StaticArray, as...) = _broadcast_sizes((t..., Size(a)), as...)
@@ -23,7 +27,7 @@ function broadcasted_index(oldsize, newindex)
2327
return sub2ind(oldsize, index...)
2428
end
2529

26-
@generated function _broadcast(f, s::Tuple{Vararg{Size}}, a::Union{Number, StaticArray}...)
30+
@generated function _broadcast(f, s::Tuple{Vararg{Size}}, a...)
2731
first_staticarray = 0
2832
for i = 1:length(a)
2933
if a[i] <: StaticArray
@@ -57,7 +61,7 @@ end
5761
current_ind = ones(Int, length(newsize))
5862

5963
while more
60-
exprs_vals = [(a[i] <: Number ? :(a[$i]) : :(a[$i][$(broadcasted_index(sizes[i], current_ind))])) for i = 1:length(sizes)]
64+
exprs_vals = [(!(a[i] <: AbstractArray) ? :(a[$i]) : :(a[$i][$(broadcasted_index(sizes[i], current_ind))])) for i = 1:length(sizes)]
6165
exprs[current_ind...] = :(f($(exprs_vals...)))
6266

6367
# increment current_ind (maybe use CartesianRange?)
@@ -77,7 +81,7 @@ end
7781
end
7882
end
7983

80-
eltype_exprs = [:(eltype($t)) for t a]
84+
eltype_exprs = [t <: AbstractArray ? :($(eltype(t))) : :($t) for t a]
8185
newtype_expr = :(Core.Inference.return_type(f, Tuple{$(eltype_exprs...)}))
8286

8387
return quote

src/indexing.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ end
1414

1515
@generated function _getindex_scalar(::Size{S}, a::StaticArray, inds::Int...) where S
1616
stride = 1
17+
ind_expr = :()
1718
for i 1:length(inds)
1819
if i == 1
1920
ind_expr = :(inds[1])
@@ -34,6 +35,7 @@ end
3435

3536
@generated function _setindex!_scalar(::Size{S}, a::StaticArray, value, inds::Int...) where S
3637
stride = 1
38+
ind_expr = :()
3739
for i 1:length(inds)
3840
if i == 1
3941
ind_expr = :(inds[1])

src/util.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ end
5050

5151
@generated function check_array_parameters{Size,T,N,L}(::Type{Size}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}})
5252
if !all(x->isa(x, Int), Size.parameters)
53-
throw(ArgumentError("Static Array parameter Size must be a tuple of Ints (e.g. `SArray{Tuple{3,3}}` or `SMatrix{3,3}`)."))
53+
return :(throw(ArgumentError("Static Array parameter Size must be a tuple of Ints (e.g. `SArray{Tuple{3,3}}` or `SMatrix{3,3}`).")))
5454
end
5555

5656
if L != tuple_prod(Size) || L < 0 || tuple_minimum(Size) < 0 || tuple_length(Size) != N
57-
throw(ArgumentError("Size mismatch in Static Array parameters. Got size $Size, dimension $N and length $L."))
57+
return :(throw(ArgumentError("Size mismatch in Static Array parameters. Got size $Size, dimension $N and length $L.")))
5858
end
5959

6060
return nothing

test/fixed_size_arrays.jl

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,39 @@ using Base.Test
55
import StaticArrays.FixedSizeArrays: @fixed_vector
66

77

8-
@compat const Vec1d = Vec{1, Float64}
9-
@compat const Vec2d = Vec{2, Float64}
10-
@compat const Vec3d = Vec{3, Float64}
11-
@compat const Vec4d = Vec{4, Float64}
12-
@compat const Vec3f = Vec{3, Float32}
8+
const Vec1d = Vec{1, Float64}
9+
const Vec2d = Vec{2, Float64}
10+
const Vec3d = Vec{3, Float64}
11+
const Vec4d = Vec{4, Float64}
12+
const Vec3f = Vec{3, Float32}
1313

14-
@compat const Mat2d = Mat{2,2, Float64, 4}
15-
@compat const Mat3d = Mat{3,3, Float64, 9}
16-
@compat const Mat4d = Mat{4,4, Float64, 16}
14+
const Mat2d = Mat{2,2, Float64, 4}
15+
const Mat3d = Mat{3,3, Float64, 9}
16+
const Mat4d = Mat{4,4, Float64, 16}
1717

18-
immutable RGB{T} <: FieldVector{T}
18+
immutable RGB{T} <: FieldVector{3, T}
1919
x::T
2020
y::T
2121
z::T
2222
end
23+
2324
RGB{T}(x::T) = RGB{T}(x, x, x)
2425
(::RGB{T}){T}(r, g, b) = RGB{T}(T(r), T(g), T(b))
2526
(::RGB{T}){T}(r::Real) = RGB(T(r), T(r), T(r))
2627
StaticArrays.similar_type{SV <: RGB, T}(::Type{SV}, ::Type{T}, ::Size{(3,)}) = RGB{T}
2728

2829
# TODO find equivalent in StaticArrays
29-
# testset "scalar nan" begin
30-
# for (p, r) in (
31-
# (Point{2, Float32}(NaN, 1), true),
32-
# (Point{2, Float64}(1, NaN), true),
33-
# (Vec{11, Float64}(NaN), true),
34-
# (Point{2, Float32}(1, 1), false),
35-
# (RGB{Float32}(NaN), true),
36-
# )
37-
# @fact isnan(p) == r
38-
# end
39-
# end
30+
@testset "scalar nan" begin
31+
for (p, r) in (
32+
(Point{2, Float32}(NaN, 1), true),
33+
(Point{2, Float64}(1, NaN), true),
34+
(Vec{11, Float64}(NaN), true),
35+
(Point{2, Float32}(1, 1), false),
36+
(RGB{Float32}(NaN, NaN, NaN), true),
37+
)
38+
@test any(isnan, p) == r
39+
end
40+
end
4041

4142
# methods I needed to define:
4243

@@ -124,8 +125,8 @@ rand(Mat{4,2, Int})
124125
@test typeof(rand(Mat{4,2, Int})) == Mat{4,2, Int, 8}
125126
@test typeof(rand(Vec{7, Int})) == Vec{7, Int}
126127

127-
@test typeof(rand(-20f0:0.192f0:230f0, Mat4d)) == Mat4d
128-
@test typeof(rand(-20f0:0.192f0:230f0, Mat{4,21,Float32})) == Mat{4,21,Float32, 4*21}
128+
# @test typeof(rand(-20f0:0.192f0:230f0, Mat4d)) == Mat4d
129+
# @test typeof(rand(-20f0:0.192f0:230f0, Mat{4,21,Float32})) == Mat{4,21,Float32, 4*21}
129130

130131
@test typeof(rand(Vec4d, 5,5)) == Matrix{Vec4d}
131132
#end
@@ -206,13 +207,13 @@ map(-, Vec(1,2,3))
206207
map(+, Vec(1,2,3), Vec(1,1, 1))
207208
(+).(Vec(1,2,3), 1.0)
208209
v1 = Vec3d(1,2,3)
209-
@test v1[(2,1)] == Vec2d(2,1)
210+
@test v1[Vec(2,1)] == Vec2d(2,1)
210211

211212
@test @inferred(-v1) == Vec(-1.0,-2.0,-3.0)
212213
@test isa(-v1, Vec3d) == true
213214
@test @inferred(v1 ./ v1) == Vec3d(1.0,1.0,1.0)
214215
@test (<).(Vec(1,3), Vec(2,2)) === Vec{2,Bool}(true, false)
215-
216+
#
216217
v1 = Vec(1.0,2.0,3.0)
217218
v2 = Vec(6.0,5.0,4.0)
218219
vi = Vec(1,2,3)
@@ -379,10 +380,9 @@ const unaryOps = (
379380
# vec-vec and vec-scalar
380381
const binaryOps = (
381382

382-
.+, .-, .*, ./, .\,
383-
.==, .!=, .<, .<=, .>, .>=, +, -,
383+
+, -, *, /, \,
384+
==, !=, <, <=, >, >=,
384385
min, max,
385-
386386
atan2, besselj, bessely, hankelh1, hankelh2,
387387
besseli, besselk, beta, lbeta
388388
)
@@ -400,7 +400,7 @@ const binaryOps = (
400400
@testset "$op with $v1 and $v2" begin
401401
try # really bad tests, but better than nothing...
402402
if applicable(op, v1[1], v2[1]) && typeof(op(v1[1], v2[1])) == eltype(v1)
403-
r = op(v1, v2)
403+
r = op.(v1, v2)
404404
for j=1:length(v1)
405405
@test r[j] == op(v1[j], v2[j])
406406
end
@@ -417,7 +417,7 @@ const binaryOps = (
417417
@testset "$op with $t" begin
418418
try
419419
if applicable(op, t[1]) && typeof(op(t[1])) == eltype(t)
420-
v = op(t)
420+
v = op.(t)
421421
for i=1:length(v)
422422
@test v[i] == op(t[i])
423423
end

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ using Base.Test
2525
include("solve.jl") # Strange inference / world-age error
2626
include("eigen.jl")
2727
include("deque.jl")
28-
#include("fixed_size_arrays.jl")
28+
include("fixed_size_arrays.jl")
2929
end

0 commit comments

Comments
 (0)