Skip to content

Commit acfff71

Browse files
author
Andy Ferris
committed
Simplified the Size trait
1 parent 918431b commit acfff71

File tree

3 files changed

+36
-58
lines changed

3 files changed

+36
-58
lines changed

src/StaticArrays.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export Scalar, SArray, SVector, SMatrix
1313
export MArray, MVector, MMatrix
1414
export FieldVector, MutableFieldVector
1515

16-
export Size, SizeOf
16+
export Size
1717

1818
export @SVector, @SMatrix, @SArray
1919
export @MVector, @MMatrix, @MArray

src/det.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
@inline det(A::StaticMatrix) = det(SizeOf(A), A)
1+
@inline det(A::StaticMatrix) = _det(Size(A), A)
22

33
"""
44
det(Size(m,m), mat)
55
66
Calculate the matrix determinate using an algorithm specialized on the size of
77
the `m`×`m` matrix `mat`, which is much faster for small matrices.
88
"""
9-
@inline det(::Type{Size{(1,1)}}, A::AbstractMatrix) = @inbounds return A[1]
9+
@inline _det(::Size{(1,1)}, A::AbstractMatrix) = @inbounds return A[1]
1010

11-
@inline function det(::Type{Size{(2,2)}}, A::AbstractMatrix)
11+
@inline function _det(::Size{(2,2)}, A::AbstractMatrix)
1212
@inbounds return A[1]*A[4] - A[3]*A[2]
1313
end
1414

15-
@inline function det(::Type{Size{(3,3)}}, A::AbstractMatrix)
15+
@inline function _det(::Size{(3,3)}, A::AbstractMatrix)
1616
@inbounds x0 = SVector(A[1], A[2], A[3])
1717
@inbounds x1 = SVector(A[4], A[5], A[6])
1818
@inbounds x2 = SVector(A[7], A[8], A[9])
1919
return vecdot(x0, cross(x1, x2))
2020
end
2121

22-
@generated function det{S,T}(::Type{Size{S}}, A::AbstractMatrix{T})
22+
@generated function _det{S,T}(::Size{S}, A::AbstractMatrix{T})
2323
if S[1] != S[2]
2424
throw(DimensionMismatch("matrix is not square"))
2525
end

src/traits.jl

Lines changed: 30 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,48 @@
11
"""
2-
SizeOf(static_array)
3-
4-
Returns the size of a static array, wrapped in a `Size` trait such as
5-
`Size{(2,3)}` for a 2×3 matrix.
2+
Size(static_array)
3+
Size(StaticArrayType)
4+
Size(dims...)
65
7-
`SizeOf` implements the "traitor" paradigm for traits, whereby an abstract trait
8-
class `SizeOf` returns a direct subtype, in this case `Size`.
6+
A trait type allowing convenient trait-based dispatch on the size of a statically
7+
sized array. The dimensions are stored as a type parameter and are statically
8+
propagated by the compiler.
99
1010
For example,
1111
```
12-
det(x::StaticMatrix) = det(SizeOf(x), x)
13-
det(::Type{Size{1,1}}, x::AbstractMatrix) = x[1,1]
14-
det(::Type{Size{2,2}}, x::AbstractMatrix) = x[1,1]*x[2,2] - x[1,2]*x[2,1]
12+
det(x::StaticMatrix) = _det(Size(x), x)
13+
_det(::Size{(1,1)}, x::StaticMatrix) = x[1,1]
14+
_det(::Size{(2,2)}, x::StaticMatrix) = x[1,1]*x[2,2] - x[1,2]*x[2,1]
1515
# and other definitions as necessary
1616
```
1717
"""
18-
abstract SizeOf
18+
immutable Size{S}
19+
function Size()
20+
check_size(S)
21+
new()
22+
end
23+
end
1924

25+
@pure check_size(S::Tuple{Vararg{Int}}) = nothing
26+
check_size(S) = error("Size was expected to be a tuple of `Int`s")
2027

21-
"""
22-
Size{(dims...)} <: SizeOf
23-
24-
A trait type allowing convenient trait-based dispatch on the size of a statically
25-
sized array.
28+
@pure Size{SA<:StaticArray}(::Type{SA}) = Size{size(SA)}()
29+
@inline Size(a::StaticArray) = Size(typeof(a))
2630

27-
`Size` implements the "traitor" paradigm for traits, whereby an abstract trait
28-
class `SizeOf` returns a direct subtype, in this case `Size`.
31+
@pure Size(s::Tuple{Vararg{Int}}) = Size{s}()
32+
@pure Size(s::Int...) = Size{s}()
2933

30-
For example,
31-
```
32-
det(x::StaticMatrix) = det(SizeOf(x), x)
33-
det(::Type{Size{1,1}}, x::AbstractMatrix) = x[1,1]
34-
det(::Type{Size{2,2}}, x::AbstractMatrix) = x[1,1]*x[2,2] - x[1,2]*x[2,1]
35-
# and other definitions as necessary
36-
```
37-
"""
38-
immutable Size{S} <: SizeOf
39-
end
34+
Base.show{S}(io::IO, ::Size{S}) = print(io, "Size", S)
4035

41-
@pure SizeOf{SA<:StaticArray}(::Type{SA}) = Size{size(SA)}
42-
@inline SizeOf(a::StaticArray) = Size(typeof(a))
4336

44-
# Also define these, since may be more convenient than SizeOf
45-
"""
46-
Size(static_array)
47-
Size(StaticArrayType)
37+
# Some @pure convenience functions.
4838

49-
Convenience constructor for the `Size` of a static array. See also `SizeOf`.
50-
"""
51-
@pure Size{SA<:StaticArray}(::Type{SA}) = Size{size(SA)}
52-
@inline Size(a::StaticArray) = Size(typeof(a))
39+
# (This type could *probably* be returned from the `size()` function.
40+
# This might enable some generic programming, e.g. with `similar(A, size(A))`.)
5341

54-
"""
55-
Size((dims...))
56-
Size(dims...)
42+
@pure getindex{S}(::Size{S}, i::Int) = S[i]
5743

58-
Pure function that constructs a compile-time constant `Size` of an array. This
59-
allows for dispatch of standard (dynamically-sized) arrays to faster, specialized
60-
*StaticArrays* library methods when the programmer knows or can reasonably infer
61-
the size. For example,
62-
```
63-
mat = [1.0 2.0; 3.0 4.0]
64-
det(Size(2,2), mat) # Faster than det(mat)
65-
```
66-
"""
67-
@pure Size(s::Tuple{Vararg{Int}}) = Size{s}
68-
@pure Size(s::Int...) = Size{s}
44+
@pure Base.:(==){S}(::Size{S}, s::Tuple{Vararg{Int}}) = S == s
45+
@pure Base.:(==){S}(s::Tuple{Vararg{Int}}, ::Size{S}) = s == S
6946

70-
@pure getindex{S}(::Type{Size{S}}, i::Int) = S[i]
47+
@pure Base.:(!=){S}(::Size{S}, s::Tuple{Vararg{Int}}) = S != s
48+
@pure Base.:(!=){S}(s::Tuple{Vararg{Int}}, ::Size{S}) = s != S

0 commit comments

Comments
 (0)