31
31
using Base. Broadcast: ziptype
32
32
end
33
33
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
- else
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)))
43
- end
44
- end
45
- end
46
-
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)))
51
- else
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)))
57
- end
58
- end
59
- end
60
-
61
- eltype_nullable (x:: Nullable ) = eltype (x)
62
- eltype_nullable (x) = typeof (x)
63
-
64
- eltypes () = Tuple{}
65
- eltypes (x) = Tuple{eltype_nullable (x)}
66
- eltypes (x, xs... ) = Tuple{eltype_nullable (x), eltypes (xs... ). parameters... }
67
-
68
- hasnulls () = false
69
- hasnulls (x) = isnull (x)
70
- hasnulls (x, xs... ) = hasnulls (x) | hasnulls (xs... )
71
-
72
- _unsafe_get (x) = (unsafe_get (x),)
73
- _unsafe_get (x, xs... ) = (unsafe_get (x), _unsafe_get (xs... )... )
74
-
75
- """
76
- broadcast_lift(f, xs...)
77
-
78
- Lift function `f`, passing it arguments `xs...`, using standard lifting semantics:
79
- for a function call `f(xs...)`, return null if any `x` in `xs` is null; otherwise,
80
- return `f` applied to values of `xs`.
81
- """
82
- @inline function broadcast_lift (f, xs... )
83
- if null_safe_op (f, eltype_nullable .(xs)... )
84
- return @compat Nullable (f (_unsafe_get (xs... )... ), ! hasnulls (xs... ))
85
- else
86
- U = Core. Inference. return_type (f, eltypes (xs... ))
87
- if hasnulls (xs... )
88
- return Nullable {U} ()
89
- else
90
- return Nullable (f (_unsafe_get (xs... )... ))
91
- end
92
- end
93
- end
94
-
95
34
call_broadcast {F, N} (f:: F , dest, As:: Vararg{NullableArray, N} ) =
96
35
invoke (broadcast!, Tuple{Function, AbstractArray, Vararg{AbstractArray, N}}, f, dest, As... )
97
36
@@ -109,14 +48,14 @@ of `broadcast` (i.e. without lifting).
109
48
"""
110
49
function Base. broadcast {F, N} (f:: F , As:: Vararg{NullableArray, N} )
111
50
# 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 (x1, x2, x3) = broadcast_lift (f, x1, x2, x3)
115
- f2 (x1, x2, x3, x4) = broadcast_lift (f, x1, x2, x3, x4)
116
- f2 (x1, x2, x3, x4, x5) = broadcast_lift (f, x1, x2, x3, x4, x5)
117
- f2 (x1, x2, x3, x4, x5, x6) = broadcast_lift (f, x1, x2, x3, x4, x5, x6)
118
- f2 (x1, x2, x3, x4, x5, x6, x7) = broadcast_lift (f, x1, x2, x3, x4, x5, x6, x7)
119
- f2 (x... ) = broadcast_lift (f, x... )
51
+ f2 (x1) = lift (f, x1)
52
+ f2 (x1, x2) = lift (f, x1, x2)
53
+ f2 (x1, x2, x3) = lift (f, x1, x2, x3)
54
+ f2 (x1, x2, x3, x4) = lift (f, x1, x2, x3, x4)
55
+ f2 (x1, x2, x3, x4, x5) = lift (f, x1, x2, x3, x4, x5)
56
+ f2 (x1, x2, x3, x4, x5, x6) = lift (f, x1, x2, x3, x4, x5, x6)
57
+ f2 (x1, x2, x3, x4, x5, x6, x7) = lift (f, x1, x2, x3, x4, x5, x6, x7)
58
+ f2 (x... ) = lift (f, x... )
120
59
121
60
T = _default_eltype (Base. Generator{ziptype (As... ), ftype (f2, As... )})
122
61
if isleaftype (T) && ! (T <: Nullable )
@@ -141,20 +80,20 @@ of `broadcast!` (i.e. without lifting).
141
80
"""
142
81
function Base. broadcast! {F, N} (f:: F , dest:: NullableArray , As:: Vararg{NullableArray, N} )
143
82
# These definitions are needed to avoid allocation due to splatting
144
- f2 (x1) = broadcast_lift (f, x1)
145
- f2 (x1, x2) = broadcast_lift (f, x1, x2)
146
- f2 (x1, x2, x3) = broadcast_lift (f, x1, x2, x3)
147
- f2 (x1, x2, x3, x4) = broadcast_lift (f, x1, x2, x3, x4)
148
- f2 (x1, x2, x3, x4, x5) = broadcast_lift (f, x1, x2, x3, x4, x5)
149
- f2 (x1, x2, x3, x4, x5, x6) = broadcast_lift (f, x1, x2, x3, x4, x5, x6)
150
- f2 (x1, x2, x3, x4, x5, x6, x7) = broadcast_lift (f, x1, x2, x3, x4, x5, x6, x7)
151
- f2 (x... ) = broadcast_lift (f, x... )
83
+ f2 (x1) = lift (f, x1)
84
+ f2 (x1, x2) = lift (f, x1, x2)
85
+ f2 (x1, x2, x3) = lift (f, x1, x2, x3)
86
+ f2 (x1, x2, x3, x4) = lift (f, x1, x2, x3, x4)
87
+ f2 (x1, x2, x3, x4, x5) = lift (f, x1, x2, x3, x4, x5)
88
+ f2 (x1, x2, x3, x4, x5, x6) = lift (f, x1, x2, x3, x4, x5, x6)
89
+ f2 (x1, x2, x3, x4, x5, x6, x7) = lift (f, x1, x2, x3, x4, x5, x6, x7)
90
+ f2 (x... ) = lift (f, x... )
152
91
call_broadcast (f2, dest, As... )
153
92
end
154
93
155
94
# To fix ambiguity
156
95
function Base. broadcast! {F} (f:: F , dest:: NullableArray )
157
- f2 () = broadcast_lift (f)
96
+ f2 () = lift (f)
158
97
call_broadcast (f2, dest)
159
98
end
160
99
0 commit comments