31
31
using Base. Broadcast: ziptype
32
32
end
33
33
34
- @inline @generated function broadcast_lift {F, T} (f :: F , x:: NTuple{1, T} )
35
- if null_safe_op (f. instance , eltype (T ))
36
- return :( Nullable (f (unsafe_get (x[ 1 ] )), ! isnull (x[ 1 ])) )
34
+ @inline function broadcast_lift (f , x)
35
+ if null_safe_op (f, eltype (x ))
36
+ return @compat Nullable (f (unsafe_get (x)), ! isnull (x) )
37
37
else
38
- U = Core. Inference. return_type (f. instance, Tuple{eltype (T)})
39
- return quote
40
- if isnull (x)
41
- return Nullable {$U} ()
42
- else
43
- return Nullable (f (unsafe_get (x[1 ])))
44
- end
38
+ U = Core. Inference. return_type (f, Tuple{eltype (x)})
39
+ if isnull (x)
40
+ return Nullable {U} ()
41
+ else
42
+ return Nullable (f (unsafe_get (x)))
45
43
end
46
44
end
47
45
end
48
46
49
- @inline @generated function broadcast_lift {F, S, T} (f :: F , x :: Tuple{S, T} )
50
- if null_safe_op (f. instance , eltype (S ), eltype (T ))
51
- return :( Nullable (f (unsafe_get (x[ 1 ] ), unsafe_get (x[ 2 ] )),
52
- ! (isnull (x[ 1 ] ) | isnull (x[ 2 ]))) )
47
+ @inline function broadcast_lift (f, x1, x2 )
48
+ if null_safe_op (f, eltype (x1 ), eltype (x2 ))
49
+ return @compat Nullable (f (unsafe_get (x1 ), unsafe_get (x2 )),
50
+ ! (isnull (x1 ) | isnull (x2)) )
53
51
else
54
- U = Core. Inference. return_type (f. instance, Tuple{eltype (S), eltype (T)})
55
- return quote
56
- if isnull (x[1 ]) | isnull (x[2 ])
57
- return Nullable {$U} ()
58
- else
59
- return Nullable (f (unsafe_get (x[1 ]), unsafe_get (x[2 ])))
60
- end
52
+ U = Core. Inference. return_type (f, Tuple{eltype (x1), eltype (x2)})
53
+ if isnull (x1) | isnull (x2)
54
+ return Nullable {U} ()
55
+ else
56
+ return Nullable (f (unsafe_get (x1), unsafe_get (x2)))
61
57
end
62
58
end
63
59
end
@@ -67,27 +63,25 @@ eltypes(x) = Tuple{eltype(x)}
67
63
eltypes (x, xs... ) = Tuple{eltype (x), eltypes (xs... ). parameters... }
68
64
69
65
"""
70
- broadcast_lift(f, x )
66
+ broadcast_lift(f, xs... )
71
67
72
- Lift function `f`, passing it arguments from the tuple `x `, using standard lifting semantics:
73
- for a function call `f(x ...)`, return null if any `x` in `x ` is null; otherwise,
74
- return `f` applied to values of `x `.
68
+ Lift function `f`, passing it arguments `xs... `, using standard lifting semantics:
69
+ for a function call `f(xs ...)`, return null if any `x` in `xs ` is null; otherwise,
70
+ return `f` applied to values of `xs `.
75
71
"""
76
- @inline @generated function broadcast_lift {F} (f :: F , x :: Tuple )
77
- if null_safe_op (f. instance , eltypes (x ). parameters... )
72
+ @inline function broadcast_lift (f, xs ... )
73
+ if null_safe_op (f, eltypes (xs ). parameters... )
78
74
# TODO : find a more efficient approach than mapreduce
79
75
# (i.e. one which gets lowered to just isnull(x1) | isnull(x2) | ...)
80
- return :( Nullable (f (unsafe_get .(x) ), ! mapreduce (isnull, | , x)) )
76
+ return @compat Nullable (f (unsafe_get .(xs) ... ), ! mapreduce (isnull, | , xs) )
81
77
else
82
- U = Core. Inference. return_type (f. instance, eltypes (x))
83
- return quote
84
- # TODO : find a more efficient approach than mapreduce
85
- # (i.e. one which gets lowered to just isnull(x1) | isnull(x2) | ...)
86
- if mapreduce (isnull, | , x)
87
- return Nullable {$U} ()
88
- else
89
- return Nullable (f (map (unsafe_get, x)... ))
90
- end
78
+ U = Core. Inference. return_type (f, eltypes (xs... ))
79
+ # TODO : find a more efficient approach than mapreduce
80
+ # (i.e. one which gets lowered to just isnull(x1) | isnull(x2) | ...)
81
+ if mapreduce (isnull, | , xs)
82
+ return Nullable {U} ()
83
+ else
84
+ return Nullable (f (map (unsafe_get, xs)... ))
91
85
end
92
86
end
93
87
end
@@ -109,9 +103,9 @@ of `broadcast` (i.e. without lifting).
109
103
"""
110
104
function Base. broadcast {F, N} (f:: F , As:: Vararg{NullableArray, N} )
111
105
# These definitions are needed to avoid allocation due to splatting
112
- f2 (x1) = broadcast_lift (f, (x1,) )
113
- f2 (x1, x2) = broadcast_lift (f, ( x1, x2) )
114
- f2 (x... ) = broadcast_lift (f, x)
106
+ f2 (x1) = broadcast_lift (f, x1 )
107
+ f2 (x1, x2) = broadcast_lift (f, x1, x2)
108
+ f2 (x... ) = broadcast_lift (f, x... )
115
109
116
110
T = _default_eltype (Base. Generator{ziptype (As... ), ftype (f2, As... )})
117
111
if isleaftype (T) && ! (T <: Nullable )
@@ -136,15 +130,15 @@ of `broadcast!` (i.e. without lifting).
136
130
"""
137
131
function Base. broadcast! {F, N} (f:: F , dest:: NullableArray , As:: Vararg{NullableArray, N} )
138
132
# These definitions are needed to avoid allocation due to splatting
139
- f2 (x1) = broadcast_lift (f, (x1,) )
140
- f2 (x1, x2) = broadcast_lift (f, ( x1, x2) )
141
- f2 (x... ) = broadcast_lift (f, x)
133
+ f2 (x1) = broadcast_lift (f, x1 )
134
+ f2 (x1, x2) = broadcast_lift (f, x1, x2)
135
+ f2 (x... ) = broadcast_lift (f, x... )
142
136
call_broadcast (f2, dest, As... )
143
137
end
144
138
145
139
# To fix ambiguity
146
140
function Base. broadcast! {F} (f:: F , dest:: NullableArray )
147
- f2 () = broadcast_lift (f, () )
141
+ f2 () = broadcast_lift (f)
148
142
call_broadcast (f2, dest)
149
143
end
150
144
0 commit comments