@@ -12,29 +12,16 @@ _fill_tuples{N}(inner, originalSZ, SZ::NTuple{N, Int}, inds::Int...) =
12
12
ntuple (i-> _fill_tuples (inner, originalSZ, SZ[1 : end - 1 ], i, inds... ), Val{SZ[end ]})
13
13
fill_tuples {N} (inner, SZ:: NTuple{N, Int} ) = _fill_tuples (inner, SZ, SZ)
14
14
15
- @generated function call {FSA <: FixedArray, T1 <: FixedArray} (:: Type{FSA} , a:: T1 , b... )
16
- SZ = size_or (FSA, nothing )
17
- ElType = eltype_or (FSA, eltype (T1))
18
- a_expr = :( a )
19
- if SZ != nothing
20
- if (prod (SZ) > (length (T1) + length (b)))
21
- throw (DimensionMismatch (" $FSA is too small, can not be constructed from array $a and $b arguments" ))
22
- elseif prod (SZ) < length (T1) && isempty (b) # shrinking constructor, e.g. Vec3(Vec4(...))
23
- a_expr = :( a[1 : $ (prod (SZ))] )
24
- end
25
- end
26
- if isempty (b)
27
- if ElType != eltype (T1) && FSA <: T1
28
- return :( map ($ ElType, $ a_expr) )
29
- elseif ElType == eltype (T1) && ! (FSA <: T1 )
30
- return :( $ FSA ($ a_expr... ) )
31
- else
32
- return :( $ FSA ($ a_expr... ) )
33
- end
34
- else
35
- return :( $ FSA (a... , b... ) )
36
- end
37
- end
15
+
16
+ #=
17
+ Constructors for homogenous non tuple arguments
18
+ Is unrolled for the first 4, since a::T... leads to slow performance
19
+ =#
20
+ call {FSA <: FixedArray, T} (:: Type{FSA} , a:: T ) = FSA (NTuple {1,T} ((a,)))
21
+ call {FSA <: FixedArray, T} (:: Type{FSA} , a:: T , b:: T ) = FSA (NTuple {2,T} ((a,b)))
22
+ call {FSA <: FixedArray, T} (:: Type{FSA} , a:: T , b:: T , c:: T ) = FSA (NTuple {3,T} ((a,b,c)))
23
+ call {FSA <: FixedArray, T} (:: Type{FSA} , a:: T , b:: T , c:: T , d:: T ) = FSA (NTuple {4,T} ((a,b,c,d)))
24
+ call {FSA <: FixedArray, T} (:: Type{FSA} , a:: T... ) = FSA (a)
38
25
39
26
immutable ParseFunctor{T, S <: AbstractString } <: Func{1}
40
27
t:: Type{T}
43
30
call {T} (pf:: ParseFunctor{T} , i:: Int ) = parse (T, pf. a[i])
44
31
call (pf:: ParseFunctor{Void} , i:: Int ) = parse (pf. a[i])
45
32
33
+
34
+ """
35
+ Constructs a fixedsize array from a Base.Array
36
+ """
46
37
@generated function call {FSA <: FixedArray, T <: Array} (:: Type{FSA} , a:: T )
47
38
if eltype (a) <: AbstractString
48
39
ElType = eltype_or (FSA, Void)
@@ -56,48 +47,91 @@ call(pf::ParseFunctor{Void}, i::Int) = parse(pf.a[i])
56
47
tupexpr = fill_tuples_expr ((i,inds... ) -> :($ ElType (a[$ i, $ (inds... )])), SZ)
57
48
expr = :($ FSA ($ tupexpr))
58
49
end
59
- if FSA <: FixedVectorNoTuple
60
- expr = :($ FSA (a... ))
61
- end
62
50
quote
63
51
$ SZ != size (a) && throw (DimensionMismatch (" size of $FSA is not fitting array $(typeof (a)) , with size: $(size (a)) " ))
64
52
$ expr
65
53
end
66
54
end
67
55
68
- call {FSA <: FixedVectorNoTuple} (:: Type{FSA} , a:: Tuple , b:: Tuple... ) = throw (DimensionMismatch (" $FSA can't be constructed from $a " ))
69
- call {FSA <: FixedVectorNoTuple} (:: Type{FSA} , a:: Tuple ) = FSA (a... )
70
- call {FSA <: FixedArray, T} (:: Type{FSA} , a:: T... ) = FSA (a)
71
-
72
-
73
56
57
+ """
58
+ Constructor for singular arguments.
59
+ Can be a tuple, is not declared as that, because it will generate ambigouities
60
+ and overwrites the default constructor.
61
+ """
74
62
@generated function call {FSA <: FixedArray, X} (:: Type{FSA} , a:: X )
75
- SZ = size_or (FSA, (1 ,))
76
- ElType = eltype_or (FSA, a)
77
- Len = prod (SZ)
78
- T_N = FSA
79
- if FSA <: FixedVectorNoTuple
80
- return :($ T_N ($ (ntuple (i-> :($ ElType (a)), Len)... )))
63
+ ND = ndims (FSA)
64
+ if X <: Tuple
65
+ types_svec = a. parameters
66
+ if all (x-> x <: Tuple , types_svec) && ND == 1
67
+ return :(throw (
68
+ DimensionMismatch (" tried to construct $FSA from $a . I can't allow that!" )
69
+ ))
70
+ end
71
+ orlen = length (types_svec)
72
+ ortyp = promote_type (types_svec... )
73
+ else
74
+ orlen = 1
75
+ ortyp = a
76
+ end
77
+ SZ = size_or (FSA, (orlen, ntuple (x-> 1 , ND- 1 )... ))
78
+ T = eltype_or (FSA, ortyp)
79
+ FSAT = similar (FSA, T, SZ)
80
+ if X <: Tuple
81
+ expr = fill_tuples_expr ((inds... )-> :($ T (a[$ (inds[1 ])])), SZ)
81
82
else
82
- expr = fill_tuples_expr ((inds... )-> :($ ElType (a[1 ])), SZ)
83
- return :($ T_N ($ expr))
83
+ expr = fill_tuples_expr ((inds... )-> :($ T (a)), SZ)
84
84
end
85
+ return :($ FSAT ($ expr))
85
86
end
86
-
87
+ """
88
+ Constructors for heterogenous multiple arguments.
89
+ E.g. 1, 2f0, 4.0
90
+ """
87
91
@generated function call {FSA <: FixedArray} (:: Type{FSA} , a... )
88
92
SZ = size_or (FSA, (length (a),))
89
93
ElType = eltype_or (FSA, promote_type (a... ))
90
- if FSA <: FixedVectorNoTuple
91
- length (a) != prod (SZ) && throw (DimensionMismatch (" can't construct $FSA with $(length (a)) arguments. Args: $a " ))
92
- return :($ FSA (map ($ ElType, a)... ))
93
- else
94
- all (x-> x <: Tuple , a) && return :( $ FSA (a) ) # TODO be smarter about this
95
- any (x-> x != ElType, a) && return :($ FSA (map ($ ElType, a)))
96
- return :($ FSA (a))
97
- end
94
+ all (x-> x <: Tuple , a) && return :( $ FSA (a) ) # TODO be smarter about this
95
+ any (x-> x != ElType, a) && return :($ FSA (map ($ ElType, a)))
96
+ return :($ FSA (a))
98
97
end
99
98
100
-
99
+ """
100
+ Construction from other FixedSizeArrays + X arguments
101
+ E.g. Vec4f0(Vec3f0(1), 0)
102
+ """
103
+ @generated function call {FSA <: FixedArray, T1 <: FixedArray} (:: Type{FSA} , a:: T1 , b... )
104
+ if isempty (b) # this is the conversion constructor for 2 FSA's
105
+ # easiest way is to just construct from the tuple
106
+ expr = :(FSA (get_tuple (a)))
107
+ if size_or (FSA, nothing ) == nothing # no concrete size
108
+ return expr
109
+ else # has a size
110
+ len1 = size (FSA, 1 )
111
+ len2 = size (T1, 1 )
112
+ if len1 < len2 # we need to shrink
113
+ return :(FSA (get_tuple (a)[1 : $ len1]))
114
+ elseif len1== len2
115
+ return expr
116
+ else
117
+ return :(throw (DimensionMismatch (
118
+ " tried to create $FSA from $T1 . The latter has too many elements"
119
+ )))
120
+ end
121
+ end
122
+ end
123
+ SZ = size_or (FSA, nothing )
124
+ ElType = eltype_or (FSA, eltype (T1))
125
+ a_expr = :( a )
126
+ if SZ != nothing
127
+ if (prod (SZ) > (length (T1) + length (b)))
128
+ throw (DimensionMismatch (" $FSA is too small, can not be constructed from array $a and $b arguments" ))
129
+ elseif prod (SZ) < length (T1) && isempty (b) # shrinking constructor, e.g. Vec3(Vec4(...))
130
+ a_expr = :( a[1 : $ (prod (SZ))] )
131
+ end
132
+ end
133
+ return :( $ FSA (a... , b... ) )
134
+ end
101
135
102
136
@inline zero {FSA <: FixedArray} (:: Type{FSA} ) = map (ConstFunctor (zero (eltype (FSA))), FSA)
103
137
zero (fsa:: FixedArray ) = zero (typeof (fsa))
0 commit comments