• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37527

pending completion
#37527

push

local

web-flow
make `IRShow.method_name` inferrable (#49607)

18 of 18 new or added lines in 3 files covered. (100.0%)

68710 of 81829 relevant lines covered (83.97%)

33068903.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.53
/base/broadcast.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
"""
4
    Base.Broadcast
5

6
Module containing the broadcasting implementation.
7
"""
8
module Broadcast
9

10
using .Base.Cartesian
11
using .Base: Indices, OneTo, tail, to_shape, isoperator, promote_typejoin, promote_typejoin_union,
12
             _msk_end, unsafe_bitgetindex, bitcache_chunks, bitcache_size, dumpbitcache, unalias, negate
13
import .Base: copy, copyto!, axes
14
export broadcast, broadcast!, BroadcastStyle, broadcast_axes, broadcastable, dotview, @__dot__, BroadcastFunction
15

16
## Computing the result's axes: deprecated name
17
const broadcast_axes = axes
18

19
### Objects with customized broadcasting behavior should declare a BroadcastStyle
20

21
"""
22
`BroadcastStyle` is an abstract type and trait-function used to determine behavior of
23
objects under broadcasting. `BroadcastStyle(typeof(x))` returns the style associated
24
with `x`. To customize the broadcasting behavior of a type, one can declare a style
25
by defining a type/method pair
26

27
    struct MyContainerStyle <: BroadcastStyle end
28
    Base.BroadcastStyle(::Type{<:MyContainer}) = MyContainerStyle()
29

30
One then writes method(s) (at least [`similar`](@ref)) operating on
31
`Broadcasted{MyContainerStyle}`. There are also several pre-defined subtypes of `BroadcastStyle`
32
that you may be able to leverage; see the
33
[Interfaces chapter](@ref man-interfaces-broadcasting) for more information.
34
"""
35
abstract type BroadcastStyle end
36

37
struct Unknown <: BroadcastStyle end
38
BroadcastStyle(::Type{Union{}}, slurp...) = Unknown()  # ambiguity resolution
×
39

40
"""
41
`Broadcast.Style{C}()` defines a [`BroadcastStyle`](@ref) signaling through the type
42
parameter `C`. You can use this as an alternative to creating custom subtypes of `BroadcastStyle`,
43
for example
44

45
    Base.BroadcastStyle(::Type{<:MyContainer}) = Broadcast.Style{MyContainer}()
46
"""
47
struct Style{T} <: BroadcastStyle end
3✔
48

49
BroadcastStyle(::Type{<:Tuple}) = Style{Tuple}()
559,767✔
50

51
"""
52
`Broadcast.AbstractArrayStyle{N} <: BroadcastStyle` is the abstract supertype for any style
53
associated with an `AbstractArray` type.
54
The `N` parameter is the dimensionality, which can be handy for AbstractArray types
55
that only support specific dimensionalities:
56

57
    struct SparseMatrixStyle <: Broadcast.AbstractArrayStyle{2} end
58
    Base.BroadcastStyle(::Type{<:SparseMatrixCSC}) = SparseMatrixStyle()
59

60
For `AbstractArray` types that support arbitrary dimensionality, `N` can be set to `Any`:
61

62
    struct MyArrayStyle <: Broadcast.AbstractArrayStyle{Any} end
63
    Base.BroadcastStyle(::Type{<:MyArray}) = MyArrayStyle()
64

65
In cases where you want to be able to mix multiple `AbstractArrayStyle`s and keep track
66
of dimensionality, your style needs to support a [`Val`](@ref) constructor:
67

68
    struct MyArrayStyleDim{N} <: Broadcast.AbstractArrayStyle{N} end
69
    (::Type{<:MyArrayStyleDim})(::Val{N}) where N = MyArrayStyleDim{N}()
70

71
Note that if two or more `AbstractArrayStyle` subtypes conflict, broadcasting machinery
72
will fall back to producing `Array`s. If this is undesirable, you may need to
73
define binary [`BroadcastStyle`](@ref) rules to control the output type.
74

75
See also [`Broadcast.DefaultArrayStyle`](@ref).
76
"""
77
abstract type AbstractArrayStyle{N} <: BroadcastStyle end
78

79
"""
80
`Broadcast.ArrayStyle{MyArrayType}()` is a [`BroadcastStyle`](@ref) indicating that an object
81
behaves as an array for broadcasting. It presents a simple way to construct
82
[`Broadcast.AbstractArrayStyle`](@ref)s for specific `AbstractArray` container types.
83
Broadcast styles created this way lose track of dimensionality; if keeping track is important
84
for your type, you should create your own custom [`Broadcast.AbstractArrayStyle`](@ref).
85
"""
86
struct ArrayStyle{A<:AbstractArray} <: AbstractArrayStyle{Any} end
85✔
87
ArrayStyle{A}(::Val) where A = ArrayStyle{A}()
×
88

89
"""
90
`Broadcast.DefaultArrayStyle{N}()` is a [`BroadcastStyle`](@ref) indicating that an object
91
behaves as an `N`-dimensional array for broadcasting. Specifically, `DefaultArrayStyle` is
92
used for any
93
`AbstractArray` type that hasn't defined a specialized style, and in the absence of
94
overrides from other `broadcast` arguments the resulting output type is `Array`.
95
When there are multiple inputs to `broadcast`, `DefaultArrayStyle` "loses" to any other [`Broadcast.ArrayStyle`](@ref).
96
"""
97
struct DefaultArrayStyle{N} <: AbstractArrayStyle{N} end
576,401✔
98
DefaultArrayStyle(::Val{N}) where N = DefaultArrayStyle{N}()
×
99
DefaultArrayStyle{M}(::Val{N}) where {N,M} = DefaultArrayStyle{N}()
76,896✔
100
const DefaultVectorStyle = DefaultArrayStyle{1}
101
const DefaultMatrixStyle = DefaultArrayStyle{2}
102
BroadcastStyle(::Type{<:AbstractArray{T,N}}) where {T,N} = DefaultArrayStyle{N}()
2,723,015✔
103
BroadcastStyle(::Type{T}) where {T} = DefaultArrayStyle{ndims(T)}()
12,025,781✔
104

105
# `ArrayConflict` is an internal type signaling that two or more different `AbstractArrayStyle`
106
# objects were supplied as arguments, and that no rule was defined for resolving the
107
# conflict. The resulting output is `Array`. While this is the same output type
108
# produced by `DefaultArrayStyle`, `ArrayConflict` "poisons" the BroadcastStyle so that
109
# 3 or more arguments still return an `ArrayConflict`.
110
struct ArrayConflict <: AbstractArrayStyle{Any} end
12✔
111
ArrayConflict(::Val) = ArrayConflict()
×
112

113
### Binary BroadcastStyle rules
114
"""
115
    BroadcastStyle(::Style1, ::Style2) = Style3()
116

117
Indicate how to resolve different `BroadcastStyle`s. For example,
118

119
    BroadcastStyle(::Primary, ::Secondary) = Primary()
120

121
would indicate that style `Primary` has precedence over `Secondary`.
122
You do not have to (and generally should not) define both argument orders.
123
The result does not have to be one of the input arguments, it could be a third type.
124

125
Please see the [Interfaces chapter](@ref man-interfaces-broadcasting) of the manual for
126
more information.
127
"""
128
BroadcastStyle(::S, ::S) where S<:BroadcastStyle = S() # homogeneous types preserved
×
129
# Fall back to Unknown. This is necessary to implement argument-swapping
130
BroadcastStyle(::BroadcastStyle, ::BroadcastStyle) = Unknown()
1,949✔
131
# Unknown loses to everything
132
BroadcastStyle(::Unknown, ::Unknown) = Unknown()
×
133
BroadcastStyle(::S, ::Unknown) where S<:BroadcastStyle = S()
×
134
# Precedence rules
135
BroadcastStyle(a::AbstractArrayStyle{0}, b::Style{Tuple}) = b
×
136
BroadcastStyle(a::AbstractArrayStyle, ::Style{Tuple})    = a
1,947✔
137
BroadcastStyle(::A, ::A) where A<:ArrayStyle             = A()
×
138
BroadcastStyle(::ArrayStyle, ::ArrayStyle)               = Unknown()
17✔
139
BroadcastStyle(::A, ::A) where A<:AbstractArrayStyle     = A()
×
140
function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}
26,221✔
141
    if Base.typename(A) === Base.typename(B)
26,221✔
142
        return A(Val(max(M, N)))
×
143
    end
144
    return Unknown()
26,221✔
145
end
146
# Any specific array type beats DefaultArrayStyle
147
BroadcastStyle(a::AbstractArrayStyle{Any}, ::DefaultArrayStyle) = a
28✔
148
BroadcastStyle(a::AbstractArrayStyle{N}, ::DefaultArrayStyle{N}) where N = a
12,068✔
149
BroadcastStyle(a::AbstractArrayStyle{M}, ::DefaultArrayStyle{N}) where {M,N} =
80,115✔
150
    typeof(a)(Val(max(M, N)))
151

152
### Lazy-wrapper for broadcasting
153

154
# `Broadcasted` wrap the arguments to `broadcast(f, args...)`. A statement like
155
#    y = x .* (x .+ 1)
156
# will result in code that is essentially
157
#    y = copy(Broadcasted(*, x, Broadcasted(+, x, 1)))
158
# `broadcast!` results in `copyto!(dest, Broadcasted(...))`.
159

160
# The use of `Nothing` in place of a `BroadcastStyle` has a different
161
# application, in the fallback method
162
#    copyto!(dest, bc::Broadcasted) = copyto!(dest, convert(Broadcasted{Nothing}, bc))
163
# This allows methods
164
#    copyto!(dest::DestType,  bc::Broadcasted{Nothing})
165
# that specialize on `DestType` to be easily disambiguated from
166
# methods that instead specialize on `BroadcastStyle`,
167
#    copyto!(dest::AbstractArray, bc::Broadcasted{MyStyle})
168

169
struct Broadcasted{Style<:Union{Nothing,BroadcastStyle}, Axes, F, Args<:Tuple} <: Base.AbstractBroadcasted
170
    style::Style
171
    f::F
172
    args::Args
173
    axes::Axes          # the axes of the resulting object (may be bigger than implied by `args` if this is nested inside a larger `Broadcasted`)
174

175
    Broadcasted(style::Union{Nothing,BroadcastStyle}, f::Tuple, args::Tuple) = error() # disambiguation: tuple is not callable
×
176
    function Broadcasted(style::Union{Nothing,BroadcastStyle}, f::F, args::Tuple, axes=nothing) where {F}
33,414,671✔
177
        # using Core.Typeof rather than F preserves inferrability when f is a type
178
        return new{typeof(style), typeof(axes), Core.Typeof(f), typeof(args)}(style, f, args, axes)
33,423,425✔
179
    end
180

181
    function Broadcasted(f::F, args::Tuple, axes=nothing) where {F}
24✔
182
        Broadcasted(combine_styles(args...)::BroadcastStyle, f, args, axes)
24✔
183
    end
184

185
    function Broadcasted{Style}(f::F, args, axes=nothing) where {Style, F}
2✔
186
        return new{Style, typeof(axes), Core.Typeof(f), typeof(args)}(Style()::Style, f, args, axes)
2✔
187
    end
188

189
    function Broadcasted{Style,Axes,F,Args}(f, args, axes) where {Style,Axes,F,Args}
3,099,061✔
190
        return new{Style, Axes, F, Args}(Style()::Style, f, args, axes)
3,099,061✔
191
    end
192
end
193

194
struct AndAnd end
195
const andand = AndAnd()
196
broadcasted(::AndAnd, a, b) = broadcasted((a, b) -> a && b, a, b)
×
197
function broadcasted(::AndAnd, a, bc::Broadcasted)
10✔
198
    bcf = flatten(bc)
10✔
199
    broadcasted((a, args...) -> a && bcf.f(args...), a, bcf.args...)
76✔
200
end
201
struct OrOr end
202
const oror = OrOr()
203
broadcasted(::OrOr, a, b) = broadcasted((a, b) -> a || b, a, b)
×
204
function broadcasted(::OrOr, a, bc::Broadcasted)
9✔
205
    bcf = flatten(bc)
9✔
206
    broadcasted((a, args...) -> a || bcf.f(args...), a, bcf.args...)
73✔
207
end
208

209
Base.convert(::Type{Broadcasted{NewStyle}}, bc::Broadcasted{<:Any,Axes,F,Args}) where {NewStyle,Axes,F,Args} =
3,101,309✔
210
    Broadcasted{NewStyle,Axes,F,Args}(bc.f, bc.args, bc.axes)::Broadcasted{NewStyle,Axes,F,Args}
211

212
function Base.show(io::IO, bc::Broadcasted{Style}) where {Style}
×
213
    print(io, Broadcasted)
×
214
    # Only show the style parameter if we have a set of axes — representing an instantiated
215
    # "outermost" Broadcasted. The styles of nested Broadcasteds represent an intermediate
216
    # computation that is not relevant for dispatch, confusing, and just extra line noise.
217
    bc.axes isa Tuple && print(io, "{", Style, "}")
×
218
    print(io, "(", bc.f, ", ", bc.args, ")")
×
219
    nothing
×
220
end
221

222
## Allocating the output container
223
Base.similar(bc::Broadcasted, ::Type{T}) where {T} = similar(bc, T, axes(bc))
3,071,803✔
224
Base.similar(::Broadcasted{DefaultArrayStyle{N}}, ::Type{ElType}, dims) where {N,ElType} =
3,060,561✔
225
    similar(Array{ElType}, dims)
226
Base.similar(::Broadcasted{DefaultArrayStyle{N}}, ::Type{Bool}, dims) where N =
11,239✔
227
    similar(BitArray, dims)
228
# In cases of conflict we fall back on Array
229
Base.similar(::Broadcasted{ArrayConflict}, ::Type{ElType}, dims) where ElType =
6✔
230
    similar(Array{ElType}, dims)
231
Base.similar(::Broadcasted{ArrayConflict}, ::Type{Bool}, dims) =
×
232
    similar(BitArray, dims)
233

234
@inline Base.axes(bc::Broadcasted) = _axes(bc, bc.axes)
94,675,301✔
235
_axes(::Broadcasted, axes::Tuple) = axes
84,044,516✔
236
@inline _axes(bc::Broadcasted, ::Nothing)  = combine_axes(bc.args...)
592,033✔
237
_axes(bc::Broadcasted{<:AbstractArrayStyle{0}}, ::Nothing) = ()
10,036,495✔
238

239
@inline Base.axes(bc::Broadcasted{<:Any, <:NTuple{N}}, d::Integer) where N =
9✔
240
    d <= N ? axes(bc)[d] : OneTo(1)
241

242
BroadcastStyle(::Type{<:Broadcasted{Style}}) where {Style} = Style()
197,069✔
243
BroadcastStyle(::Type{<:Broadcasted{S}}) where {S<:Union{Nothing,Unknown}} =
×
244
    throw(ArgumentError("Broadcasted{Unknown} wrappers do not have a style assigned"))
245

246
argtype(::Type{BC}) where {BC<:Broadcasted} = fieldtype(BC, :args)
×
247
argtype(bc::Broadcasted) = argtype(typeof(bc))
×
248

249
@inline Base.eachindex(bc::Broadcasted) = _eachindex(axes(bc))
3,089,182✔
250
_eachindex(t::Tuple{Any}) = t[1]
2,412,838✔
251
_eachindex(t::Tuple) = CartesianIndices(t)
145,479✔
252

253
Base.IndexStyle(bc::Broadcasted) = IndexStyle(typeof(bc))
10✔
254
Base.IndexStyle(::Type{<:Broadcasted{<:Any,<:Tuple{Any}}}) = IndexLinear()
5✔
255
Base.IndexStyle(::Type{<:Broadcasted{<:Any}}) = IndexCartesian()
5✔
256

257
Base.LinearIndices(bc::Broadcasted{<:Any,<:Tuple{Any}}) = LinearIndices(axes(bc))::LinearIndices{1}
2✔
258

259
Base.ndims(bc::Broadcasted) = ndims(typeof(bc))
8,978✔
260
Base.ndims(::Type{<:Broadcasted{<:Any,<:NTuple{N,Any}}}) where {N} = N
8,992✔
261

262
Base.size(bc::Broadcasted) = map(length, axes(bc))
47✔
263
Base.length(bc::Broadcasted) = prod(size(bc))
2✔
264

265
function Base.iterate(bc::Broadcasted)
48✔
266
    iter = eachindex(bc)
48✔
267
    iterate(bc, (iter,))
84✔
268
end
269
Base.@propagate_inbounds function Base.iterate(bc::Broadcasted, s)
2,397✔
270
    y = iterate(s...)
4,539✔
271
    y === nothing && return nothing
2,397✔
272
    i, newstate = y
2,352✔
273
    return (bc[i], (s[1], newstate))
2,352✔
274
end
275

276
Base.IteratorSize(::Type{T}) where {T<:Broadcasted} = Base.HasShape{ndims(T)}()
34✔
277
Base.ndims(BC::Type{<:Broadcasted{<:Any,Nothing}}) = _maxndims(fieldtype(BC, :args))
24✔
278
Base.ndims(::Type{<:Broadcasted{<:AbstractArrayStyle{N},Nothing}}) where {N<:Integer} = N
×
279

280
_maxndims(T::Type{<:Tuple}) = reduce(max, (ntuple(n -> _ndims(fieldtype(T, n)), Base._counttuple(T))))
20✔
281
_maxndims(::Type{<:Tuple{T}}) where {T} = ndims(T)
×
282
_maxndims(::Type{<:Tuple{T}}) where {T<:Tuple} = _ndims(T)
×
283
function _maxndims(::Type{<:Tuple{T, S}}) where {T, S}
19✔
284
    return T<:Tuple || S<:Tuple ? max(_ndims(T), _ndims(S)) : max(ndims(T), ndims(S))
19✔
285
end
286

287
_ndims(x) = ndims(x)
18✔
288
_ndims(::Type{<:Tuple}) = 1
5✔
289

290
Base.IteratorEltype(::Type{<:Broadcasted}) = Base.EltypeUnknown()
16✔
291

292
## Instantiation fills in the "missing" fields in Broadcasted.
293
instantiate(x) = x
×
294

295
"""
296
    Broadcast.instantiate(bc::Broadcasted)
297

298
Construct and check the axes for the lazy Broadcasted object `bc`.
299

300
Custom [`BroadcastStyle`](@ref)s may override this default in cases where it is fast and easy
301
to compute and verify the resulting `axes` on-demand, leaving the `axis` field
302
of the `Broadcasted` object empty (populated with [`nothing`](@ref)).
303
"""
304
@inline function instantiate(bc::Broadcasted)
3,102,032✔
305
    if bc.axes isa Nothing # Not done via dispatch to make it easier to extend instantiate(::Broadcasted{Style})
3,102,032✔
306
        axes = combine_axes(bc.args...)
3,079,074✔
307
    else
308
        axes = bc.axes
29,055✔
309
        check_broadcast_axes(axes, bc.args...)
32,163✔
310
    end
311
    return Broadcasted(bc.style, bc.f, bc.args, axes)
3,105,952✔
312
end
313
instantiate(bc::Broadcasted{<:AbstractArrayStyle{0}}) = bc
10,037,732✔
314
# Tuples don't need axes, but when they have axes (for .= assignment), we need to check them (#33020)
315
instantiate(bc::Broadcasted{Style{Tuple}, Nothing}) = bc
278,933✔
316
function instantiate(bc::Broadcasted{Style{Tuple}})
1,863✔
317
    check_broadcast_axes(bc.axes, bc.args...)
1,867✔
318
    return bc
1,859✔
319
end
320
## Flattening
321

322
"""
323
    bcf = flatten(bc)
324

325
Create a "flat" representation of a lazy-broadcast operation.
326
From
327
   f.(a, g.(b, c), d)
328
we produce the equivalent of
329
   h.(a, b, c, d)
330
where
331
   h(w, x, y, z) = f(w, g(x, y), z)
332
In terms of its internal representation,
333
   Broadcasted(f, a, Broadcasted(g, b, c), d)
334
becomes
335
   Broadcasted(h, a, b, c, d)
336

337
This is an optional operation that may make custom implementation of broadcasting easier in
338
some cases.
339
"""
340
function flatten(bc::Broadcasted)
10,080✔
341
    isflat(bc) && return bc
10,080✔
342
    # concatenate the nested arguments into {a, b, c, d}
343
    args = cat_nested(bc)
15✔
344
    # build a function `makeargs` that takes a "flat" argument list and
345
    # and creates the appropriate input arguments for `f`, e.g.,
346
    #          makeargs = (w, x, y, z) -> (w, g(x, y), z)
347
    #
348
    # `makeargs` is built recursively and looks a bit like this:
349
    #     makeargs(w, x, y, z) = (w, makeargs1(x, y, z)...)
350
    #                          = (w, g(x, y), makeargs2(z)...)
351
    #                          = (w, g(x, y), z)
352
    let makeargs = make_makeargs(()->(), bc.args), f = bc.f
41✔
353
        newf = @inline function(args::Vararg{Any,N}) where N
41✔
354
            f(makeargs(args...)...)
26✔
355
        end
356
        return Broadcasted(bc.style, newf, args, bc.axes)
15✔
357
    end
358
end
359

360
const NestedTuple = Tuple{<:Broadcasted,Vararg{Any}}
361
isflat(bc::Broadcasted) = _isflat(bc.args)
11,627✔
362
_isflat(args::NestedTuple) = false
15✔
363
_isflat(args::Tuple) = _isflat(tail(args))
29,166✔
364
_isflat(args::Tuple{}) = true
×
365

366
cat_nested(t::Broadcasted, rest...) = (cat_nested(t.args...)..., cat_nested(rest...)...)
335✔
367
cat_nested(t::Any, rest...) = (t, cat_nested(rest...)...)
484✔
368
cat_nested() = ()
632✔
369

370
"""
371
    make_makeargs(makeargs_tail::Function, t::Tuple) -> Function
372

373
Each element of `t` is one (consecutive) node in a broadcast tree.
374
Ignoring `makeargs_tail` for the moment, the job of `make_makeargs` is
375
to return a function that takes in flattened argument list and returns a
376
tuple (each entry corresponding to an entry in `t`, having evaluated
377
the corresponding element in the broadcast tree). As an additional
378
complication, the passed in tuple may be longer than the number of leaves
379
in the subtree described by `t`. The `makeargs_tail` function should
380
be called on such additional arguments (but not the arguments consumed
381
by `t`).
382
"""
383
@inline make_makeargs(makeargs_tail, t::Tuple{}) = makeargs_tail
41✔
384
@inline function make_makeargs(makeargs_tail, t::Tuple)
44✔
385
    makeargs = make_makeargs(makeargs_tail, tail(t))
44✔
386
    (head, tail...)->(head, makeargs(tail...)...)
103✔
387
end
388
function make_makeargs(makeargs_tail, t::Tuple{<:Broadcasted, Vararg{Any}})
26✔
389
    bc = t[1]
26✔
390
    # c.f. the same expression in the function on leaf nodes above. Here
391
    # we recurse into siblings in the broadcast tree.
392
    let makeargs_tail = make_makeargs(makeargs_tail, tail(t)),
26✔
393
            # Here we recurse into children. It would be valid to pass in makeargs_tail
394
            # here, and not use it below. However, in that case, our recursion is no
395
            # longer purely structural because we're building up one argument (the closure)
396
            # while destructuing another.
397
            makeargs_head = make_makeargs((args...)->args, bc.args),
55✔
398
            f = bc.f
399
        # Create two functions, one that splits of the first length(bc.args)
400
        # elements from the tuple and one that yields the remaining arguments.
401
        # N.B. We can't call headargs on `args...` directly because
402
        # args is flattened (i.e. our children have not been evaluated
403
        # yet).
404
        headargs, tailargs = make_headargs(bc.args), make_tailargs(bc.args)
26✔
405
        return @inline function(args::Vararg{Any,N}) where N
81✔
406
            args1 = makeargs_head(args...)
55✔
407
            a, b = headargs(args1...), makeargs_tail(tailargs(args1...)...)
55✔
408
            (f(a...), b...)
55✔
409
        end
410
    end
411
end
412

413
@inline function make_headargs(t::Tuple)
40✔
414
    let headargs = make_headargs(tail(t))
40✔
415
        return @inline function(head, tail::Vararg{Any,N}) where N
102✔
416
            (head, headargs(tail...)...)
62✔
417
        end
418
    end
419
end
420
@inline function make_headargs(::Tuple{})
26✔
421
    return @inline function(tail::Vararg{Any,N}) where N
81✔
422
        ()
55✔
423
    end
424
end
425

426
@inline function make_tailargs(t::Tuple)
40✔
427
    let tailargs = make_tailargs(tail(t))
40✔
428
        return @inline function(head, tail::Vararg{Any,N}) where N
102✔
429
            tailargs(tail...)
62✔
430
        end
431
    end
432
end
433
@inline function make_tailargs(::Tuple{})
26✔
434
    return @inline function(tail::Vararg{Any,N}) where N
81✔
435
        tail
55✔
436
    end
437
end
438

439
## Broadcasting utilities ##
440

441
## logic for deciding the BroadcastStyle
442

443
"""
444
    combine_styles(cs...) -> BroadcastStyle
445

446
Decides which `BroadcastStyle` to use for any number of value arguments.
447
Uses [`BroadcastStyle`](@ref) to get the style for each argument, and uses
448
[`result_style`](@ref) to combine styles.
449

450
# Examples
451

452
```jldoctest
453
julia> Broadcast.combine_styles([1], [1 2; 3 4])
454
Base.Broadcast.DefaultArrayStyle{2}()
455
```
456
"""
457
function combine_styles end
458

459
combine_styles() = DefaultArrayStyle{0}()
15✔
460
combine_styles(c) = result_style(BroadcastStyle(typeof(c)))
15,558,967✔
461
combine_styles(c1, c2) = result_style(combine_styles(c1), combine_styles(c2))
2,977,034✔
462
@inline combine_styles(c1, c2, cs...) = result_style(combine_styles(c1), combine_styles(c2, cs...))
42,608✔
463

464
"""
465
    result_style(s1::BroadcastStyle[, s2::BroadcastStyle]) -> BroadcastStyle
466

467
Takes one or two `BroadcastStyle`s and combines them using [`BroadcastStyle`](@ref) to
468
determine a common `BroadcastStyle`.
469

470
# Examples
471

472
```jldoctest
473
julia> Broadcast.result_style(Broadcast.DefaultArrayStyle{0}(), Broadcast.DefaultArrayStyle{3}())
474
Base.Broadcast.DefaultArrayStyle{3}()
475

476
julia> Broadcast.result_style(Broadcast.Unknown(), Broadcast.DefaultArrayStyle{1}())
477
Base.Broadcast.DefaultArrayStyle{1}()
478
```
479
"""
480
function result_style end
481

482
result_style(s::BroadcastStyle) = s
385,061✔
483
result_style(s1::S, s2::S) where S<:BroadcastStyle = S()
151,674✔
484
# Test both orders so users typically only have to declare one order
485
result_style(s1, s2) = result_join(s1, s2, BroadcastStyle(s1, s2), BroadcastStyle(s2, s1))
67,125✔
486

487
# result_join is the final arbiter. Because `BroadcastStyle` for undeclared pairs results in Unknown,
488
# we defer to any case where the result of `BroadcastStyle` is known.
489
result_join(::Any, ::Any, ::Unknown, ::Unknown)   = Unknown()
×
490
result_join(::Any, ::Any, ::Unknown, s::BroadcastStyle) = s
13,059✔
491
result_join(::Any, ::Any, s::BroadcastStyle, ::Unknown) = s
15,212✔
492
# For AbstractArray types with specialized broadcasting and undefined precedence rules,
493
# we have to signal conflict. Because ArrayConflict is a subtype of AbstractArray,
494
# this will "poison" any future operations (if we instead returned `DefaultArrayStyle`, then for
495
# 3-array broadcasting the returned type would depend on argument order).
496
result_join(::AbstractArrayStyle, ::AbstractArrayStyle, ::Unknown, ::Unknown) =
10✔
497
    ArrayConflict()
498
# Fallbacks in case users define `rule` for both argument-orders (not recommended)
499
result_join(::Any, ::Any, ::S, ::S) where S<:BroadcastStyle = S()
38,843✔
500
@noinline function result_join(::S, ::T, ::U, ::V) where {S,T,U,V}
1✔
501
    error("""
1✔
502
conflicting broadcast rules defined
503
  Broadcast.BroadcastStyle(::$S, ::$T) = $U()
504
  Broadcast.BroadcastStyle(::$T, ::$S) = $V()
505
One of these should be undefined (and thus return Broadcast.Unknown).""")
506
end
507

508
# Indices utilities
509

510
"""
511
    combine_axes(As...) -> Tuple
512

513
Determine the result axes for broadcasting across all values in `As`.
514

515
```jldoctest
516
julia> Broadcast.combine_axes([1], [1 2; 3 4; 5 6])
517
(Base.OneTo(3), Base.OneTo(2))
518

519
julia> Broadcast.combine_axes(1, 1, 1)
520
()
521
```
522
"""
523
@inline combine_axes(A, B...) = broadcast_shape(axes(A), combine_axes(B...))
38,529✔
524
@inline combine_axes(A, B) = broadcast_shape(axes(A), axes(B))
3,065,112✔
525
combine_axes(A) = axes(A)
607,495✔
526

527
"""
528
    broadcast_shape(As...) -> Tuple
529

530
Determine the result axes for broadcasting across all axes (size Tuples) in `As`.
531

532
```jldoctest
533
julia> Broadcast.broadcast_shape((1,2), (2,1))
534
(2, 2)
535

536
julia> Broadcast.broadcast_shape((1,), (1,5), (4,5,3))
537
(4, 5, 3)
538
```
539
"""
540
function broadcast_shape end
541
# shape (i.e., tuple-of-indices) inputs
542
broadcast_shape(shape::Tuple) = shape
277,547✔
543
broadcast_shape(shape::Tuple, shape1::Tuple, shapes::Tuple...) = broadcast_shape(_bcs(shape, shape1), shapes...)
2,996,619✔
544
# _bcs consolidates two shapes into a single output shape
545
_bcs(::Tuple{}, ::Tuple{}) = ()
×
546
_bcs(::Tuple{}, newshape::Tuple) = (newshape[1], _bcs((), tail(newshape))...)
1,645,950✔
547
_bcs(shape::Tuple, ::Tuple{}) = (shape[1], _bcs(tail(shape), ())...)
823,856✔
548
function _bcs(shape::Tuple, newshape::Tuple)
752,961✔
549
    return (_bcs1(shape[1], newshape[1]), _bcs(tail(shape), tail(newshape))...)
807,256✔
550
end
551
# _bcs1 handles the logic for a single dimension
552
_bcs1(a::Integer, b::Integer) = a == 1 ? b : (b == 1 ? a : (a == b ? a : throw(DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths $a and $b"))))
17✔
553
_bcs1(a::Integer, b) = a == 1 ? b : (first(b) == 1 && last(b) == a ? b : throw(DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths $a and $(length(b))")))
5✔
554
_bcs1(a, b::Integer) = _bcs1(b, a)
4✔
555
_bcs1(a, b) = _bcsm(b, a) ? axistype(b, a) : (_bcsm(a, b) ? axistype(a, b) : throw(DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths $(length(a)) and $(length(b))")))
807,744✔
556
# _bcsm tests whether the second index is consistent with the first
557
_bcsm(a, b) = a == b || length(b) == 1
693,653✔
558
_bcsm(a, b::Number) = b == 1
4✔
559
_bcsm(a::Number, b::Number) = a == b || b == 1
×
560
# Ensure inferrability when dealing with axes of different AbstractUnitRange types
561
# (We may not want to define general promotion rules between, say, OneTo and Slice, but if
562
#  we get here we know the axes are at least consistent for the purposes of broadcasting)
563
axistype(a::T, b::T) where T = a
16✔
564
axistype(a::OneTo, b::OneTo) = OneTo{Int}(a)
1,367✔
565
axistype(a, b) = UnitRange{Int}(a)
4✔
566

567
## Check that all arguments are broadcast compatible with shape
568
# comparing one input against a shape
569
check_broadcast_shape(shp) = nothing
×
570
check_broadcast_shape(shp, ::Tuple{}) = nothing
3,993✔
571
check_broadcast_shape(::Tuple{}, ::Tuple{}) = nothing
×
572
function check_broadcast_shape(::Tuple{}, Ashp::Tuple)
10✔
573
    if any(ax -> length(ax) != 1, Ashp)
38✔
574
        throw(DimensionMismatch("cannot broadcast array to have fewer non-singleton dimensions"))
×
575
    end
576
    nothing
10✔
577
end
578
function check_broadcast_shape(shp, Ashp::Tuple)
121,521✔
579
    _bcsm(shp[1], Ashp[1]) || throw(DimensionMismatch("array could not be broadcast to match destination"))
127,483✔
580
    check_broadcast_shape(tail(shp), tail(Ashp))
125,121✔
581
end
582
@inline check_broadcast_axes(shp, A) = check_broadcast_shape(shp, axes(A))
82,631✔
583
# comparing many inputs
584
@inline function check_broadcast_axes(shp, A, As...)
43,090✔
585
    check_broadcast_axes(shp, A)
43,949✔
586
    check_broadcast_axes(shp, As...)
42,365✔
587
end
588

589
## Indexing manipulations
590
"""
591
    newindex(argument, I)
592
    newindex(I, keep, default)
593

594
Recompute index `I` such that it appropriately constrains broadcasted dimensions to the source.
595

596
Two methods are supported, both allowing for `I` to be specified as either a [`CartesianIndex`](@ref) or
597
an `Int`.
598

599
* `newindex(argument, I)` dynamically constrains `I` based upon the axes of `argument`.
600
* `newindex(I, keep, default)` constrains `I` using the pre-computed tuples `keeps` and `defaults`.
601
    * `keep` is a tuple of `Bool`s, where `keep[d] == true` means that dimension `d` in `I` should be preserved as is
602
    * `default` is a tuple of Integers, specifying what index to use in dimension `d` when `keep[d] == false`.
603
    Any remaining indices in `I` beyond the length of the `keep` tuple are truncated. The `keep` and `default`
604
    tuples may be created by `newindexer(argument)`.
605
"""
606
Base.@propagate_inbounds newindex(arg, I::CartesianIndex) = CartesianIndex(_newindex(axes(arg), I.I))
67,504✔
607
Base.@propagate_inbounds newindex(arg, I::Integer) = CartesianIndex(_newindex(axes(arg), (I,)))
4,157✔
608
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple) = (ifelse(length(ax[1]) == 1, ax[1][1], I[1]), _newindex(tail(ax), tail(I))...)
139,558✔
609
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple) = ()
194✔
610
Base.@propagate_inbounds _newindex(ax::Tuple, I::Tuple{}) = (ax[1][1], _newindex(tail(ax), ())...)
×
611
Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = ()
71,467✔
612

613
# If dot-broadcasting were already defined, this would be `ifelse.(keep, I, Idefault)`.
614
@inline newindex(I::CartesianIndex, keep, Idefault) = CartesianIndex(_newindex(I.I, keep, Idefault))
73,456,282✔
615
@inline newindex(i::Integer, keep::Tuple, idefault) = ifelse(keep[1], i, idefault[1])
39,246,056✔
616
@inline newindex(i::Integer, keep::Tuple{}, idefault) = CartesianIndex(())
7✔
617
@inline _newindex(I, keep, Idefault) =
148,494,051✔
618
    (ifelse(keep[1], I[1], Idefault[1]), _newindex(tail(I), tail(keep), tail(Idefault))...)
619
@inline _newindex(I, keep::Tuple{}, Idefault) = ()  # truncate if keep is shorter than I
357✔
620
@inline _newindex(I::Tuple{}, keep, Idefault) = ()  # or I is shorter
20✔
621
@inline _newindex(I::Tuple{}, keep::Tuple{}, Idefault) = () # or both
73,036,401✔
622

623
# newindexer(A) generates `keep` and `Idefault` (for use by `newindex` above)
624
# for a particular array `A`; `shapeindexer` does so for its axes.
625
@inline newindexer(A) = shapeindexer(axes(A))
2,720,600✔
626
@inline shapeindexer(ax) = _newindexer(ax)
2,722,564✔
627
@inline _newindexer(indsA::Tuple{}) = (), ()
×
628
@inline function _newindexer(indsA::Tuple)
556,912✔
629
    ind1 = indsA[1]
282,264✔
630
    keep, Idefault = _newindexer(tail(indsA))
282,249✔
631
    (Base.length(ind1)::Integer != 1, keep...), (first(ind1), Idefault...)
3,004,463✔
632
end
633

634
@inline function Base.getindex(bc::Broadcasted, I::Union{Integer,CartesianIndex})
84,817,831✔
635
    @boundscheck checkbounds(bc, I)
85,533,745✔
636
    @inbounds _broadcast_getindex(bc, I)
85,959,969✔
637
end
638
Base.@propagate_inbounds Base.getindex(
639
    bc::Broadcasted,
640
    i1::Union{Integer,CartesianIndex},
641
    i2::Union{Integer,CartesianIndex},
642
    I::Union{Integer,CartesianIndex}...,
643
) =
11✔
644
    bc[CartesianIndex((i1, i2, I...))]
645
Base.@propagate_inbounds Base.getindex(bc::Broadcasted) = bc[CartesianIndex(())]
×
646

647
@inline Base.checkbounds(bc::Broadcasted, I::Union{Integer,CartesianIndex}) =
84,816,799✔
648
    Base.checkbounds_indices(Bool, axes(bc), (I,)) || Base.throw_boundserror(bc, (I,))
649

650

651
"""
652
    _broadcast_getindex(A, I)
653

654
Index into `A` with `I`, collapsing broadcasted indices to their singleton indices as appropriate.
655
"""
656
Base.@propagate_inbounds _broadcast_getindex(A::Union{Ref,AbstractArray{<:Any,0},Number}, I) = A[] # Scalar-likes can just ignore all indices
13,425,883✔
657
Base.@propagate_inbounds _broadcast_getindex(::Ref{Type{T}}, I) where {T} = T
×
658
# Tuples are statically known to be singleton or vector-like
659
Base.@propagate_inbounds _broadcast_getindex(A::Tuple{Any}, I) = A[1]
14,006✔
660
Base.@propagate_inbounds _broadcast_getindex(A::Tuple, I) = A[I[1]]
1,466,212✔
661
# Everything else falls back to dynamically dropping broadcasted indices based upon its axes
662
Base.@propagate_inbounds _broadcast_getindex(A, I) = A[newindex(A, I)]
83,898✔
663

664
# In some cases, it's more efficient to sort out which dimensions should be dropped
665
# ahead of time (often when the size checks aren't able to be lifted out of the loop).
666
# The Extruded struct computes that information ahead of time and stores it as a pair
667
# of tuples to optimize indexing later. This is most commonly needed for `Array` and
668
# other `AbstractArray` subtypes that wrap `Array` and dynamically ask it for its size.
669
struct Extruded{T, K, D}
670
    x::T
2,720,600✔
671
    keeps::K    # A tuple of booleans, specifying which indices should be passed normally
672
    defaults::D # A tuple of integers, specifying the index to use when keeps[i] is false (as defaults[i])
673
end
674
@inline axes(b::Extruded) = axes(b.x)
74✔
675
Base.@propagate_inbounds _broadcast_getindex(b::Extruded, i) = b.x[newindex(i, b.keeps, b.defaults)]
113,050,003✔
676
extrude(x::AbstractArray) = Extruded(x, newindexer(x)...)
2,720,600✔
677
extrude(x) = x
2,396,492✔
678

679
# For Broadcasted
680
Base.@propagate_inbounds function _broadcast_getindex(bc::Broadcasted{<:Any,<:Any,<:Any,<:Any}, I)
81,524,413✔
681
    args = _getindex(bc.args, I)
82,664,770✔
682
    return _broadcast_getindex_evalf(bc.f, args...)
82,298,430✔
683
end
684
# Hack around losing Type{T} information in the final args tuple. Julia actually
685
# knows (in `code_typed`) the _value_ of these types, statically displaying them,
686
# but inference is currently skipping inferring the type of the types as they are
687
# transiently placed in a tuple as the argument list is lispily constructed. These
688
# additional methods recover type stability when a `Type` appears in one of the
689
# first two arguments of a function.
690
Base.@propagate_inbounds function _broadcast_getindex(bc::Broadcasted{<:Any,<:Any,<:Any,<:Tuple{Ref{Type{T}},Vararg{Any}}}, I) where {T}
4,764,676✔
691
    args = _getindex(tail(bc.args), I)
4,765,348✔
692
    return _broadcast_getindex_evalf(bc.f, T, args...)
4,764,681✔
693
end
694
Base.@propagate_inbounds function _broadcast_getindex(bc::Broadcasted{<:Any,<:Any,<:Any,<:Tuple{Any,Ref{Type{T}},Vararg{Any}}}, I) where {T}
1,796✔
695
    arg1 = _broadcast_getindex(bc.args[1], I)
1,796✔
696
    args = _getindex(tail(tail(bc.args)), I)
1,796✔
697
    return _broadcast_getindex_evalf(bc.f, arg1, T, args...)
1,796✔
698
end
699
Base.@propagate_inbounds function _broadcast_getindex(bc::Broadcasted{<:Any,<:Any,<:Any,<:Tuple{Ref{Type{T}},Ref{Type{S}},Vararg{Any}}}, I) where {T,S}
×
700
    args = _getindex(tail(tail(bc.args)), I)
×
701
    return _broadcast_getindex_evalf(bc.f, T, S, args...)
×
702
end
703

704
# Utilities for _broadcast_getindex
705
Base.@propagate_inbounds _getindex(args::Tuple, I) = (_broadcast_getindex(args[1], I), _getindex(tail(args), I)...)
65,659,114✔
706
Base.@propagate_inbounds _getindex(args::Tuple{Any}, I) = (_broadcast_getindex(args[1], I),)
86,216,135✔
707
Base.@propagate_inbounds _getindex(args::Tuple{}, I) = ()
2,217✔
708

709
@inline _broadcast_getindex_evalf(f::Tf, args::Vararg{Any,N}) where {Tf,N} = f(args...)  # not propagate_inbounds
87,048,846✔
710

711
"""
712
    Broadcast.broadcastable(x)
713

714
Return either `x` or an object like `x` such that it supports [`axes`](@ref), indexing, and its type supports [`ndims`](@ref).
715

716
If `x` supports iteration, the returned value should have the same `axes` and indexing
717
behaviors as [`collect(x)`](@ref).
718

719
If `x` is not an `AbstractArray` but it supports `axes`, indexing, and its type supports
720
`ndims`, then `broadcastable(::typeof(x))` may be implemented to just return itself.
721
Further, if `x` defines its own [`BroadcastStyle`](@ref), then it must define its
722
`broadcastable` method to return itself for the custom style to have any effect.
723

724
# Examples
725
```jldoctest
726
julia> Broadcast.broadcastable([1,2,3]) # like `identity` since arrays already support axes and indexing
727
3-element Vector{Int64}:
728
 1
729
 2
730
 3
731

732
julia> Broadcast.broadcastable(Int) # Types don't support axes, indexing, or iteration but are commonly used as scalars
733
Base.RefValue{Type{Int64}}(Int64)
734

735
julia> Broadcast.broadcastable("hello") # Strings break convention of matching iteration and act like a scalar instead
736
Base.RefValue{String}("hello")
737
```
738
"""
739
broadcastable(x::Union{Symbol,AbstractString,Function,UndefInitializer,Nothing,RoundingMode,Missing,Val,Ptr,AbstractPattern,Pair,IO,CartesianIndex}) = Ref(x)
1,009✔
740
broadcastable(::Type{T}) where {T} = Ref{Type{T}}(T)
1,573,221✔
741
broadcastable(x::Union{AbstractArray,Number,AbstractChar,Ref,Tuple,Broadcasted}) = x
13,911,182✔
742
# Default to collecting iterables — which will error for non-iterables
743
broadcastable(x) = collect(x)
13✔
744
broadcastable(::Union{AbstractDict, NamedTuple}) = throw(ArgumentError("broadcasting over dictionaries and `NamedTuple`s is reserved"))
3✔
745

746
## Computation of inferred result type, for empty and concretely inferred cases only
747
_broadcast_getindex_eltype(bc::Broadcasted) = combine_eltypes(bc.f, bc.args)
3,541✔
748
_broadcast_getindex_eltype(A) = eltype(A)  # Tuple, Array, etc.
5,588,719✔
749

750
eltypes(::Tuple{}) = Tuple{}
1✔
751
eltypes(t::Tuple{Any}) = Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]))
547,383✔
752
eltypes(t::Tuple{Any,Any}) = Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]), _broadcast_getindex_eltype(t[2]))
5,054,893✔
753
# eltypes(t::Tuple) = (TT = eltypes(tail(t)); TT === Union{} ? Union{} : Iterators.TupleOrBottom(_broadcast_getindex_eltype(t[1]), TT.parameters...))
754
eltypes(t::Tuple) = Iterators.TupleOrBottom(ntuple(i -> _broadcast_getindex_eltype(t[i]), Val(length(t)))...)
27,565✔
755

756
# Inferred eltype of result of broadcast(f, args...)
757
function combine_eltypes(f, args::Tuple)
3,075,489✔
758
    argT = eltypes(args)
5,613,387✔
759
    argT === Union{} && return Union{}
3,075,481✔
760
    return promote_typejoin_union(Base._return_type(f, argT))
3,079,640✔
761
end
762

763
## Broadcasting core
764

765
"""
766
    broadcast(f, As...)
767

768
Broadcast the function `f` over the arrays, tuples, collections, [`Ref`](@ref)s and/or scalars `As`.
769

770
Broadcasting applies the function `f` over the elements of the container arguments and the
771
scalars themselves in `As`. Singleton and missing dimensions are expanded to match the
772
extents of the other arguments by virtually repeating the value. By default, only a limited
773
number of types are considered scalars, including `Number`s, `String`s, `Symbol`s, `Type`s,
774
`Function`s and some common singletons like [`missing`](@ref) and [`nothing`](@ref). All other arguments are
775
iterated over or indexed into elementwise.
776

777
The resulting container type is established by the following rules:
778

779
 - If all the arguments are scalars or zero-dimensional arrays, it returns an unwrapped scalar.
780
 - If at least one argument is a tuple and all others are scalars or zero-dimensional arrays,
781
   it returns a tuple.
782
 - All other combinations of arguments default to returning an `Array`, but
783
   custom container types can define their own implementation and promotion-like
784
   rules to customize the result when they appear as arguments.
785

786
A special syntax exists for broadcasting: `f.(args...)` is equivalent to
787
`broadcast(f, args...)`, and nested `f.(g.(args...))` calls are fused into a
788
single broadcast loop.
789

790
# Examples
791
```jldoctest
792
julia> A = [1, 2, 3, 4, 5]
793
5-element Vector{Int64}:
794
 1
795
 2
796
 3
797
 4
798
 5
799

800
julia> B = [1 2; 3 4; 5 6; 7 8; 9 10]
801
5×2 Matrix{Int64}:
802
 1   2
803
 3   4
804
 5   6
805
 7   8
806
 9  10
807

808
julia> broadcast(+, A, B)
809
5×2 Matrix{Int64}:
810
  2   3
811
  5   6
812
  8   9
813
 11  12
814
 14  15
815

816
julia> parse.(Int, ["1", "2"])
817
2-element Vector{Int64}:
818
 1
819
 2
820

821
julia> abs.((1, -2))
822
(1, 2)
823

824
julia> broadcast(+, 1.0, (0, -2.0))
825
(1.0, -1.0)
826

827
julia> (+).([[0,2], [1,3]], Ref{Vector{Int}}([1,-1]))
828
2-element Vector{Vector{Int64}}:
829
 [1, 1]
830
 [2, 2]
831

832
julia> string.(("one","two","three","four"), ": ", 1:4)
833
4-element Vector{String}:
834
 "one: 1"
835
 "two: 2"
836
 "three: 3"
837
 "four: 4"
838

839
```
840
"""
841
broadcast(f::Tf, As...) where {Tf} = materialize(broadcasted(f, As...))
8,205✔
842

843
# special cases defined for performance
844
@inline broadcast(f, x::Number...) = f(x...)
8✔
845
@inline broadcast(f, t::NTuple{N,Any}, ts::Vararg{NTuple{N,Any}}) where {N} = map(f, t, ts...)
×
846

847
"""
848
    broadcast!(f, dest, As...)
849

850
Like [`broadcast`](@ref), but store the result of
851
`broadcast(f, As...)` in the `dest` array.
852
Note that `dest` is only used to store the result, and does not supply
853
arguments to `f` unless it is also listed in the `As`,
854
as in `broadcast!(f, A, A, B)` to perform `A[:] = broadcast(f, A, B)`.
855

856
# Examples
857
```jldoctest
858
julia> A = [1.0; 0.0]; B = [0.0; 0.0];
859

860
julia> broadcast!(+, B, A, (0, -2.0));
861

862
julia> B
863
2-element Vector{Float64}:
864
  1.0
865
 -2.0
866

867
julia> A
868
2-element Vector{Float64}:
869
 1.0
870
 0.0
871

872
julia> broadcast!(+, A, A, (0, -2.0));
873

874
julia> A
875
2-element Vector{Float64}:
876
  1.0
877
 -2.0
878
```
879
"""
880
broadcast!(f::Tf, dest, As::Vararg{Any,N}) where {Tf,N} = (materialize!(dest, broadcasted(f, As...)); dest)
20,514✔
881

882
"""
883
    broadcast_preserving_zero_d(f, As...)
884

885
Like [`broadcast`](@ref), except in the case of a 0-dimensional result where it returns a 0-dimensional container
886

887
Broadcast automatically unwraps zero-dimensional results to be just the element itself,
888
but in some cases it is necessary to always return a container — even in the 0-dimensional case.
889
"""
890
@inline function broadcast_preserving_zero_d(f, As...)
148,709✔
891
    bc = broadcasted(f, As...)
148,709✔
892
    r = materialize(bc)
294,062✔
893
    return length(axes(bc)) == 0 ? fill!(similar(bc, typeof(r)), r) : r
148,709✔
894
end
895
@inline broadcast_preserving_zero_d(f) = fill(f())
×
896
@inline broadcast_preserving_zero_d(f, as::Number...) = fill(f(as...))
×
897

898
"""
899
    Broadcast.materialize(bc)
900

901
Take a lazy `Broadcasted` object and compute the result
902
"""
903
@inline materialize(bc::Broadcasted) = copy(instantiate(bc))
14,447,814✔
904
materialize(x) = x
475✔
905

906
@inline function materialize!(dest, x)
2✔
907
    return materialize!(dest, instantiate(Broadcasted(identity, (x,), axes(dest))))
2✔
908
end
909

910
@inline function materialize!(dest, bc::Broadcasted{<:Any})
38,857✔
911
    return materialize!(combine_styles(dest, bc), dest, bc)
426,751✔
912
end
913
@inline function materialize!(::BroadcastStyle, dest, bc::Broadcasted{<:Any})
38,517✔
914
    return copyto!(dest, instantiate(Broadcasted(bc.style, bc.f, bc.args, axes(dest))))
447,998✔
915
end
916

917
## general `copy` methods
918
@inline copy(bc::Broadcasted{<:AbstractArrayStyle{0}}) = bc[CartesianIndex()]
10,036,190✔
919
copy(bc::Broadcasted{<:Union{Nothing,Unknown}}) =
×
920
    throw(ArgumentError("broadcasting requires an assigned BroadcastStyle"))
921

922
const NonleafHandlingStyles = Union{DefaultArrayStyle,ArrayConflict}
923

924
@inline function copy(bc::Broadcasted)
3,067,958✔
925
    ElType = combine_eltypes(bc.f, bc.args)
5,600,065✔
926
    if Base.isconcretetype(ElType)
3,067,966✔
927
        # We can trust it and defer to the simpler `copyto!`
928
        return copyto!(similar(bc, ElType), bc)
5,607,782✔
929
    end
930
    # When ElType is not concrete, use narrowing. Use the first output
931
    # value to determine the starting output eltype; copyto_nonleaf!
932
    # will widen `dest` as needed to accommodate later values.
933
    bc′ = preprocess(nothing, bc)
316✔
934
    iter = eachindex(bc′)
315✔
935
    y = iterate(iter)
628✔
936
    if y === nothing
316✔
937
        # if empty, take the ElType at face value
938
        return similar(bc′, ElType)
4✔
939
    end
940
    # Initialize using the first value
941
    I, state = y
311✔
942
    @inbounds val = bc′[I]
476✔
943
    dest = similar(bc′, typeof(val))
450✔
944
    @inbounds dest[I] = val
453✔
945
    # Now handle the remaining values
946
    # The typeassert gives inference a helping hand on the element type and dimensionality
947
    # (work-around for #28382)
948
    ElType′ = ElType === Union{} ? Any : ElType <: Type ? Type : ElType
326✔
949
    RT = dest isa AbstractArray ? AbstractArray{<:ElType′, ndims(dest)} : Any
553✔
950
    return copyto_nonleaf!(dest, bc′, iter, state, 1)::RT
307✔
951
end
952

953
## general `copyto!` methods
954
# The most general method falls back to a method that replaces Style->Nothing
955
# This permits specialization on typeof(dest) without introducing ambiguities
956
@inline copyto!(dest::AbstractArray, bc::Broadcasted) = copyto!(dest, convert(Broadcasted{Nothing}, bc))
5,655,791✔
957

958
# Performance optimization for the common identity scalar case: dest .= val
959
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{<:AbstractArrayStyle{0}})
5,347✔
960
    # Typically, we must independently execute bc for every storage location in `dest`, but:
961
    # IF we're in the common no-op identity case with no nested args (like `dest .= val`),
962
    if bc.f === identity && bc.args isa Tuple{Any} && isflat(bc)
5,347✔
963
        # THEN we can just extract the argument and `fill!` the destination with it
964
        return fill!(dest, bc.args[1][])
390,355✔
965
    else
966
        # Otherwise, fall back to the default implementation like above
967
        return copyto!(dest, convert(Broadcasted{Nothing}, bc))
21✔
968
    end
969
end
970

971
# For broadcasted assignments like `broadcast!(f, A, ..., A, ...)`, where `A`
972
# appears on both the LHS and the RHS of the `.=`, then we know we're only
973
# going to make one pass through the array, and even though `A` is aliasing
974
# against itself, the mutations won't affect the result as the indices on the
975
# LHS and RHS will always match. This is not true in general, but with the `.op=`
976
# syntax it's fairly common for an argument to be `===` a source.
977
broadcast_unalias(dest, src) = dest === src ? src : unalias(dest, src)
8,364,836✔
978
broadcast_unalias(::Nothing, src) = src
549✔
979

980
# Preprocessing a `Broadcasted` does two things:
981
# * unaliases any arguments from `dest`
982
# * "extrudes" the arguments where it is advantageous to pre-compute the broadcasted indices
983
@inline preprocess(dest, bc::Broadcasted) = Broadcasted(bc.style, bc.f, preprocess_args(dest, bc.args), bc.axes)
5,692,680✔
984
preprocess(dest, x) = extrude(broadcast_unalias(dest, x))
8,365,008✔
985

986
@inline preprocess_args(dest, args::Tuple) = (preprocess(dest, args[1]), preprocess_args(dest, tail(args))...)
5,138,653✔
987
@inline preprocess_args(dest, args::Tuple{Any}) = (preprocess(dest, args[1]),)
4,880,873✔
988
@inline preprocess_args(dest, args::Tuple{}) = ()
9✔
989

990
# Specialize this method if all you want to do is specialize on typeof(dest)
991
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{Nothing})
3,091,958✔
992
    axes(dest) == axes(bc) || throwdm(axes(dest), axes(bc))
3,095,570✔
993
    # Performance optimization: broadcast!(identity, dest, A) is equivalent to copyto!(dest, A) if indices match
994
    if bc.f === identity && bc.args isa Tuple{AbstractArray} # only a single input argument to broadcast!
3,092,378✔
995
        A = bc.args[1]
3,472✔
996
        if axes(dest) == axes(A)
7,763✔
997
            return copyto!(dest, A)
6,995✔
998
        end
999
    end
1000
    bc′ = preprocess(dest, bc)
5,640,713✔
1001
    # Performance may vary depending on whether `@inbounds` is placed outside the
1002
    # for loop or not. (cf. https://github.com/JuliaLang/julia/issues/38086)
1003
    @inbounds @simd for I in eachindex(bc′)
3,236,818✔
1004
        dest[I] = bc′[I]
74,252,455✔
1005
    end
×
1006
    return dest
3,091,677✔
1007
end
1008

1009
# Performance optimization: for BitArray outputs, we cache the result
1010
# in a "small" Vector{Bool}, and then copy in chunks into the output
1011
@inline function copyto!(dest::BitArray, bc::Broadcasted{Nothing})
7,737✔
1012
    axes(dest) == axes(bc) || throwdm(axes(dest), axes(bc))
11,634✔
1013
    ischunkedbroadcast(dest, bc) && return chunkedcopyto!(dest, bc)
8,970✔
1014
    length(dest) < 256 && return invoke(copyto!, Tuple{AbstractArray, Broadcasted{Nothing}}, dest, bc)
19,033✔
1015
    tmp = Vector{Bool}(undef, bitcache_size)
1,420✔
1016
    destc = dest.chunks
1,420✔
1017
    cind = 1
310✔
1018
    bc′ = preprocess(dest, bc)
2,808✔
1019
    @inbounds for P in Iterators.partition(eachindex(bc′), bitcache_size)
2,840✔
1020
        ind = 1
434✔
1021
        @simd for I in P
43,215✔
1022
            tmp[ind] = bc′[I]
1,637,704✔
1023
            ind += 1
1,637,077✔
1024
        end
×
1025
        @simd for i in ind:bitcache_size
1,668✔
1026
            tmp[i] = false
4,687,147✔
1027
        end
×
1028
        dumpbitcache(destc, cind, tmp)
1,544✔
1029
        cind += bitcache_chunks
1,544✔
1030
    end
1,668✔
1031
    return dest
1,420✔
1032
end
1033

1034
# For some BitArray operations, we can work at the level of chunks. The trivial
1035
# implementation just walks over the UInt64 chunks in a linear fashion.
1036
# This requires three things:
1037
#   1. The function must be known to work at the level of chunks (or can be converted to do so)
1038
#   2. The only arrays involved must be BitArrays or scalar Bools
1039
#   3. There must not be any broadcasting beyond scalar — all array sizes must match
1040
# We could eventually allow for all broadcasting and other array types, but that
1041
# requires very careful consideration of all the edge effects.
1042
const ChunkableOp = Union{typeof(&), typeof(|), typeof(xor), typeof(~), typeof(identity),
1043
    typeof(!), typeof(*), typeof(==)} # these are convertible to chunkable ops by liftfuncs
1044
const BroadcastedChunkableOp{Style<:Union{Nothing,BroadcastStyle}, Axes, F<:ChunkableOp, Args<:Tuple} = Broadcasted{Style,Axes,F,Args}
1045
ischunkedbroadcast(R, bc::BroadcastedChunkableOp) = ischunkedbroadcast(R, bc.args)
1,012✔
1046
ischunkedbroadcast(R, args) = false
7,687✔
1047
ischunkedbroadcast(R, args::Tuple{<:BitArray,Vararg{Any}}) = size(R) == size(args[1]) && ischunkedbroadcast(R, tail(args))
1,287✔
1048
ischunkedbroadcast(R, args::Tuple{<:Bool,Vararg{Any}}) = ischunkedbroadcast(R, tail(args))
2✔
1049
ischunkedbroadcast(R, args::Tuple{<:BroadcastedChunkableOp,Vararg{Any}}) = ischunkedbroadcast(R, args[1]) && ischunkedbroadcast(R, tail(args))
3✔
1050
ischunkedbroadcast(R, args::Tuple{}) = true
2✔
1051

1052
# Convert compatible functions to chunkable ones. They must also be green-lighted as ChunkableOps
1053
liftfuncs(bc::Broadcasted{<:Any,<:Any,<:Any}) = Broadcasted(bc.style, bc.f, map(liftfuncs, bc.args), bc.axes)
46✔
1054
liftfuncs(bc::Broadcasted{<:Any,<:Any,typeof(sign)}) = Broadcasted(bc.style, identity, map(liftfuncs, bc.args), bc.axes)
×
1055
liftfuncs(bc::Broadcasted{<:Any,<:Any,typeof(!)}) = Broadcasted(bc.style, ~, map(liftfuncs, bc.args), bc.axes)
×
1056
liftfuncs(bc::Broadcasted{<:Any,<:Any,typeof(*)}) = Broadcasted(bc.style, &, map(liftfuncs, bc.args), bc.axes)
×
1057
liftfuncs(bc::Broadcasted{<:Any,<:Any,typeof(==)}) = Broadcasted(bc.style, (~)∘(xor), map(liftfuncs, bc.args), bc.axes)
2✔
1058
liftfuncs(x) = x
4✔
1059

1060
liftchunks(::Tuple{}) = ()
×
1061
liftchunks(args::Tuple{<:BitArray,Vararg{Any}}) = (args[1].chunks, liftchunks(tail(args))...)
1,279✔
1062
# Transform scalars to repeated scalars the size of a chunk
1063
liftchunks(args::Tuple{<:Bool,Vararg{Any}}) = (ifelse(args[1], typemax(UInt64), UInt64(0)), liftchunks(tail(args))...)
×
1064
ithchunk(i) = ()
×
1065
Base.@propagate_inbounds ithchunk(i, c::Vector{UInt64}, args...) = (c[i], ithchunk(i, args...)...)
2,047✔
1066
Base.@propagate_inbounds ithchunk(i, b::UInt64, args...) = (b, ithchunk(i, args...)...)
×
1067
@inline function chunkedcopyto!(dest::BitArray, bc::Broadcasted)
48✔
1068
    isempty(dest) && return dest
640✔
1069
    f = flatten(liftfuncs(bc))
48✔
1070
    args = liftchunks(f.args)
640✔
1071
    dc = dest.chunks
640✔
1072
    @simd for i in eachindex(dc)
640✔
1073
        @inbounds dc[i] = f.f(ithchunk(i, args...)...)
1,024✔
1074
    end
×
1075
    @inbounds dc[end] &= Base._msk_end(dest)
640✔
1076
    return dest
640✔
1077
end
1078

1079

1080
@noinline throwdm(axdest, axsrc) =
×
1081
    throw(DimensionMismatch("destination axes $axdest are not compatible with source axes $axsrc"))
1082

1083
function restart_copyto_nonleaf!(newdest, dest, bc, val, I, iter, state, count)
250✔
1084
    # Function barrier that makes the copying to newdest type stable
1085
    for II in Iterators.take(iter, count)
500✔
1086
        newdest[II] = dest[II]
2,221✔
1087
    end
4,184✔
1088
    newdest[I] = val
250✔
1089
    return copyto_nonleaf!(newdest, bc, iter, state, count+1)
250✔
1090
end
1091

1092
function copyto_nonleaf!(dest, bc::Broadcasted, iter, state, count)
557✔
1093
    T = eltype(dest)
556✔
1094
    while true
13,660✔
1095
        y = iterate(iter, state)
14,893✔
1096
        y === nothing && break
13,660✔
1097
        I, state = y
13,352✔
1098
        @inbounds val = bc[I]
24,995✔
1099
        if val isa T
13,353✔
1100
            @inbounds dest[I] = val
22,480✔
1101
        else
1102
            # This element type doesn't fit in dest. Allocate a new dest with wider eltype,
1103
            # copy over old values, and continue
1104
            newdest = Base.similar(bc, promote_typejoin(T, typeof(val)))
253✔
1105
            return restart_copyto_nonleaf!(newdest, dest, bc, val, I, iter, state, count)
250✔
1106
        end
1107
        count += 1
13,103✔
1108
    end
13,103✔
1109
    return dest
307✔
1110
end
1111

1112
## Tuple methods
1113

1114
@inline function copy(bc::Broadcasted{Style{Tuple}})
278,933✔
1115
    dim = axes(bc)
278,933✔
1116
    length(dim) == 1 || throw(DimensionMismatch("tuple only supports one dimension"))
278,932✔
1117
    N = length(dim[1])
278,932✔
1118
    return ntuple(k -> @inbounds(_broadcast_getindex(bc, k)), Val(N))
1,003,475✔
1119
end
1120

1121
## scalar-range broadcast operations ##
1122
# DefaultArrayStyle and \ are not available at the time of range.jl
1123
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractRange) = r
3✔
1124

1125
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractRange) = range(-first(r), step=negate(step(r)), length=length(r))
×
1126
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange) = range(-first(r), -last(r), step=negate(step(r)))
4✔
1127
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::StepRangeLen) = StepRangeLen(-r.ref, negate(r.step), length(r), r.offset)
×
1128
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::LinRange) = LinRange(-r.start, -r.stop, length(r))
×
1129

1130
# For #18336 we need to prevent promotion of the step type:
1131
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractRange, x::Number) = range(first(r) + x, step=step(r), length=length(r))
4✔
1132
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::AbstractRange) = range(x + first(r), step=step(r), length=length(r))
1✔
1133
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::OrdinalRange, x::Integer) = range(first(r) + x, last(r) + x, step=step(r))
6✔
1134
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::OrdinalRange) = range(x + first(r), x + last(r), step=step(r))
×
1135
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractUnitRange, x::Integer) = range(first(r) + x, last(r) + x)
218,628✔
1136
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::AbstractUnitRange) = range(x + first(r), x + last(r))
2,822,869✔
1137
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractUnitRange, x::Real) = range(first(r) + x, length=length(r))
4✔
1138
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Real, r::AbstractUnitRange) = range(x + first(r), length=length(r))
1✔
1139
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::StepRangeLen{T}, x::Number) where T =
27✔
1140
    StepRangeLen{typeof(T(r.ref)+x)}(r.ref + x, r.step, length(r), r.offset)
1141
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::StepRangeLen{T}) where T =
49✔
1142
    StepRangeLen{typeof(x+T(r.ref))}(x + r.ref, r.step, length(r), r.offset)
1143
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::LinRange, x::Number) = LinRange(r.start + x, r.stop + x, length(r))
×
1144
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Number, r::LinRange) = LinRange(x + r.start, x + r.stop, length(r))
1✔
1145
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r1::AbstractRange, r2::AbstractRange) = r1 + r2
16✔
1146

1147
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractRange, x::Number) = range(first(r) - x, step=step(r), length=length(r))
4✔
1148
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::AbstractRange) = range(x - first(r), step=negate(step(r)), length=length(r))
×
1149
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange, x::Integer) = range(first(r) - x, last(r) - x, step=step(r))
6✔
1150
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Integer, r::OrdinalRange) = range(x - first(r), x - last(r), step=negate(step(r)))
5✔
1151
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractUnitRange, x::Integer) = range(first(r) - x, last(r) - x)
961✔
1152
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractUnitRange, x::Real) = range(first(r) - x, length=length(r))
4✔
1153
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::StepRangeLen{T}, x::Number) where T =
19✔
1154
    StepRangeLen{typeof(T(r.ref)-x)}(r.ref - x, r.step, length(r), r.offset)
1155
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::StepRangeLen{T}) where T =
18✔
1156
    StepRangeLen{typeof(x-T(r.ref))}(x - r.ref, negate(r.step), length(r), r.offset)
1157
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::LinRange, x::Number) = LinRange(r.start - x, r.stop - x, length(r))
×
1158
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), x::Number, r::LinRange) = LinRange(x - r.start, x - r.stop, length(r))
1✔
1159
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r1::AbstractRange, r2::AbstractRange) = r1 - r2
5✔
1160

1161
# at present Base.range_start_step_length(1,0,5) is an error, so for 0 .* (-2:2) we explicitly construct StepRangeLen:
1162
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), x::Number, r::AbstractRange) = StepRangeLen(x*first(r), x*step(r), length(r))
44✔
1163
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), x::Number, r::StepRangeLen{T}) where {T} =
28✔
1164
    StepRangeLen{typeof(x*T(r.ref))}(x*r.ref, x*r.step, length(r), r.offset)
1165
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), x::Number, r::LinRange) = LinRange(x * r.start, x * r.stop, r.len)
1✔
1166
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), x::AbstractFloat, r::OrdinalRange) =
16✔
1167
    Base.range_start_step_length(x*first(r), x*step(r), length(r))  # 0.2 .* (-2:2) needs TwicePrecision
1168
# separate in case of noncommutative multiplication:
1169
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::AbstractRange, x::Number) = StepRangeLen(first(r)*x, step(r)*x, length(r))
9✔
1170
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::StepRangeLen{T}, x::Number) where {T} =
30✔
1171
    StepRangeLen{typeof(T(r.ref)*x)}(r.ref*x, r.step*x, length(r), r.offset)
1172
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::LinRange, x::Number) = LinRange(r.start * x, r.stop * x, r.len)
1✔
1173
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::OrdinalRange, x::AbstractFloat) =
4✔
1174
    Base.range_start_step_length(first(r)*x, step(r)*x, length(r))
1175

1176
#broadcasted(::DefaultArrayStyle{1}, ::typeof(/), r::AbstractRange, x::Number) = range(first(r)/x, last(r)/x, length=length(r))
1177
broadcasted(::DefaultArrayStyle{1}, ::typeof(/), r::AbstractRange, x::Number) = range(first(r)/x, step=step(r)/x, length=length(r))
13✔
1178
broadcasted(::DefaultArrayStyle{1}, ::typeof(/), r::StepRangeLen{T}, x::Number) where {T} =
24✔
1179
    StepRangeLen{typeof(T(r.ref)/x)}(r.ref/x, r.step/x, length(r), r.offset)
1180
broadcasted(::DefaultArrayStyle{1}, ::typeof(/), r::LinRange, x::Number) = LinRange(r.start / x, r.stop / x, r.len)
1✔
1181

1182
broadcasted(::DefaultArrayStyle{1}, ::typeof(\), x::Number, r::AbstractRange) = range(x\first(r), step=x\step(r), length=length(r))
1✔
1183
broadcasted(::DefaultArrayStyle{1}, ::typeof(\), x::Number, r::StepRangeLen) = StepRangeLen(x\r.ref, x\r.step, length(r), r.offset)
×
1184
broadcasted(::DefaultArrayStyle{1}, ::typeof(\), x::Number, r::LinRange) = LinRange(x \ r.start, x \ r.stop, r.len)
×
1185

1186
broadcasted(::DefaultArrayStyle{1}, ::typeof(big), r::UnitRange) = big(r.start):big(last(r))
2✔
1187
broadcasted(::DefaultArrayStyle{1}, ::typeof(big), r::StepRange) = big(r.start):big(r.step):big(last(r))
2✔
1188
broadcasted(::DefaultArrayStyle{1}, ::typeof(big), r::StepRangeLen) = StepRangeLen(big(r.ref), big(r.step), length(r), r.offset)
8✔
1189
broadcasted(::DefaultArrayStyle{1}, ::typeof(big), r::LinRange) = LinRange(big(r.start), big(r.stop), length(r))
×
1190

1191
## CartesianIndices
1192
broadcasted(::typeof(+), I::CartesianIndices{N}, j::CartesianIndex{N}) where N =
4✔
1193
    CartesianIndices(map((rng, offset)->rng .+ offset, I.indices, Tuple(j)))
8✔
1194
broadcasted(::typeof(+), j::CartesianIndex{N}, I::CartesianIndices{N}) where N =
1✔
1195
    I .+ j
1196
broadcasted(::typeof(-), I::CartesianIndices{N}, j::CartesianIndex{N}) where N =
3✔
1197
    CartesianIndices(map((rng, offset)->rng .- offset, I.indices, Tuple(j)))
6✔
1198
function broadcasted(::typeof(-), j::CartesianIndex{N}, I::CartesianIndices{N}) where N
5✔
1199
    diffrange(offset, rng) = range(offset-last(rng), length=length(rng), step=step(rng))
15✔
1200
    Iterators.reverse(CartesianIndices(map(diffrange, Tuple(j), I.indices)))
5✔
1201
end
1202

1203
## In specific instances, we can broadcast masked BitArrays whole chunks at a time
1204
# Very intentionally do not support much functionality here: scalar indexing would be O(n)
1205
struct BitMaskedBitArray{N,M}
1206
    parent::BitArray{N}
1207
    mask::BitArray{M}
1208
    BitMaskedBitArray{N,M}(parent, mask) where {N,M} = new(parent, mask)
1✔
1209
end
1210
@inline function BitMaskedBitArray(parent::BitArray{N}, mask::BitArray{M}) where {N,M}
1✔
1211
    @boundscheck checkbounds(parent, mask)
1✔
1212
    BitMaskedBitArray{N,M}(parent, mask)
1✔
1213
end
1214
Base.@propagate_inbounds dotview(B::BitArray, i::BitArray) = BitMaskedBitArray(B, i)
1✔
1215
Base.show(io::IO, B::BitMaskedBitArray) = foreach(arg->show(io, arg), (typeof(B), (B.parent, B.mask)))
×
1216
# Override materialize! to prevent the BitMaskedBitArray from escaping to an overridable method
1217
@inline materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any,<:Any,typeof(identity),Tuple{Bool}}) = fill!(B, bc.args[1])
1✔
1218
@inline materialize!(B::BitMaskedBitArray, bc::Broadcasted{<:Any}) = materialize!(@inbounds(view(B.parent, B.mask)), bc)
×
1219
function Base.fill!(B::BitMaskedBitArray, b::Bool)
1✔
1220
    Bc = B.parent.chunks
1✔
1221
    Ic = B.mask.chunks
1✔
1222
    @inbounds if b
1✔
1223
        for i = 1:length(Bc)
×
1224
            Bc[i] |= Ic[i]
×
1225
        end
×
1226
    else
1227
        for i = 1:length(Bc)
2✔
1228
            Bc[i] &= ~Ic[i]
1✔
1229
        end
1✔
1230
    end
1231
    return B
1✔
1232
end
1233

1234

1235

1236
############################################################
1237

1238
# x[...] .= f.(y...) ---> broadcast!(f, dotview(x, ...), y...).
1239
# The dotview function defaults to getindex, but we override it in
1240
# a few cases to get the expected in-place behavior without affecting
1241
# explicit calls to view.   (All of this can go away if slices
1242
# are changed to generate views by default.)
1243

1244
Base.@propagate_inbounds dotview(args...) = Base.maybeview(args...)
6,707✔
1245

1246
############################################################
1247
# The parser turns @. into a call to the __dot__ macro,
1248
# which converts all function calls and assignments into
1249
# broadcasting "dot" calls/assignments:
1250

1251
dottable(x) = false # avoid dotting spliced objects (e.g. view calls inserted by @view)
×
1252
# don't add dots to dot operators
1253
dottable(x::Symbol) = (!isoperator(x) || first(string(x)) != '.' || x === :..) && x !== :(:)
46✔
1254
dottable(x::Expr) = x.head !== :$
9✔
1255
undot(x) = x
×
1256
function undot(x::Expr)
3✔
1257
    if x.head === :.=
6✔
1258
        Expr(:(=), x.args...)
5✔
1259
    elseif x.head === :block # occurs in for x=..., y=...
1✔
1260
        Expr(:block, Base.mapany(undot, x.args)...)
1✔
1261
    else
1262
        x
×
1263
    end
1264
end
1265
__dot__(x) = x
×
1266
function __dot__(x::Expr)
107✔
1267
    dotargs = Base.mapany(__dot__, x.args)
107✔
1268
    if x.head === :call && dottable(x.args[1])
118✔
1269
        Expr(:., dotargs[1], Expr(:tuple, dotargs[2:end]...))
30✔
1270
    elseif x.head === :comparison
77✔
1271
        Expr(:comparison, (iseven(i) && dottable(arg) && arg isa Symbol && isoperator(arg) ?
3✔
1272
                               Symbol('.', arg) : arg for (i, arg) in pairs(dotargs))...)
1273
    elseif x.head === :$
74✔
1274
        x.args[1]
9✔
1275
    elseif x.head === :let # don't add dots to `let x=...` assignments
65✔
1276
        Expr(:let, undot(dotargs[1]), dotargs[2])
2✔
1277
    elseif x.head === :for # don't add dots to for x=... assignments
63✔
1278
        Expr(:for, undot(dotargs[1]), dotargs[2])
1✔
1279
    elseif (x.head === :(=) || x.head === :function || x.head === :macro) &&
69✔
1280
           Meta.isexpr(x.args[1], :call) # function or macro definition
1281
        Expr(x.head, x.args[1], dotargs[2])
1✔
1282
    elseif x.head === :(<:) || x.head === :(>:)
120✔
1283
        tmp = x.head === :(<:) ? :.<: : :.>:
3✔
1284
        Expr(:call, tmp, dotargs...)
3✔
1285
    else
1286
        head = String(x.head)::String
58✔
1287
        if last(head) == '=' && first(head) != '.' || head == "&&" || head == "||"
105✔
1288
            Expr(Symbol('.', head), dotargs...)
17✔
1289
        else
1290
            Expr(x.head, dotargs...)
41✔
1291
        end
1292
    end
1293
end
1294
"""
1295
    @. expr
1296

1297
Convert every function call or operator in `expr` into a "dot call"
1298
(e.g. convert `f(x)` to `f.(x)`), and convert every assignment in `expr`
1299
to a "dot assignment" (e.g. convert `+=` to `.+=`).
1300

1301
If you want to *avoid* adding dots for selected function calls in
1302
`expr`, splice those function calls in with `\$`.  For example,
1303
`@. sqrt(abs(\$sort(x)))` is equivalent to `sqrt.(abs.(sort(x)))`
1304
(no dot for `sort`).
1305

1306
(`@.` is equivalent to a call to `@__dot__`.)
1307

1308
# Examples
1309
```jldoctest
1310
julia> x = 1.0:3.0; y = similar(x);
1311

1312
julia> @. y = x + 3 * sin(x)
1313
3-element Vector{Float64}:
1314
 3.5244129544236893
1315
 4.727892280477045
1316
 3.4233600241796016
1317
```
1318
"""
1319
macro __dot__(x)
32✔
1320
    esc(__dot__(x))
32✔
1321
end
1322

1323
@inline function broadcasted_kwsyntax(f, args...; kwargs...)
90✔
1324
    if isempty(kwargs) # some BroadcastStyles dispatch on `f`, so try to preserve its type
45✔
1325
        return broadcasted(f, args...)
5✔
1326
    else
1327
        return broadcasted((args...) -> f(args...; kwargs...), args...)
199✔
1328
    end
1329
end
1330
@inline function broadcasted(f::F, args...) where {F}
15✔
1331
    args′ = map(broadcastable, args)
15✔
1332
    broadcasted(combine_styles(args′...), f, args′...)
15✔
1333
end
1334
# Due to the current Type{T}/DataType specialization heuristics within Tuples,
1335
# the totally generic varargs broadcasted(f, args...) method above loses Type{T}s in
1336
# mapping broadcastable across the args. These additional methods with explicit
1337
# arguments ensure we preserve Type{T}s in the first or second argument position.
1338
@inline function broadcasted(f::F, arg1, args...) where {F}
10,744,611✔
1339
    arg1′ = broadcastable(arg1)
10,640,829✔
1340
    args′ = map(broadcastable, args)
10,640,824✔
1341
    broadcasted(combine_styles(arg1′, args′...), f, arg1′, args′...)
10,641,407✔
1342
end
1343
@inline function broadcasted(f::F, arg1, arg2, args...) where {F}
3,517,522✔
1344
    arg1′ = broadcastable(arg1)
2,943,428✔
1345
    arg2′ = broadcastable(arg2)
2,943,969✔
1346
    args′ = map(broadcastable, args)
2,943,420✔
1347
    broadcasted(combine_styles(arg1′, arg2′, args′...), f, arg1′, arg2′, args′...)
5,986,533✔
1348
end
1349
@inline broadcasted(style::BroadcastStyle, f::F, args...) where {F} = Broadcasted(style, f, args)
13,585,158✔
1350

1351
"""
1352
    BroadcastFunction{F} <: Function
1353

1354
Represents the "dotted" version of an operator, which broadcasts the operator over its
1355
arguments, so `BroadcastFunction(op)` is functionally equivalent to `(x...) -> (op).(x...)`.
1356

1357
Can be created by just passing an operator preceded by a dot to a higher-order function.
1358

1359
# Examples
1360
```jldoctest
1361
julia> a = [[1 3; 2 4], [5 7; 6 8]];
1362

1363
julia> b = [[9 11; 10 12], [13 15; 14 16]];
1364

1365
julia> map(.*, a, b)
1366
2-element Vector{Matrix{Int64}}:
1367
 [9 33; 20 48]
1368
 [65 105; 84 128]
1369

1370
julia> Base.BroadcastFunction(+)(a, b) == a .+ b
1371
true
1372
```
1373

1374
!!! compat "Julia 1.6"
1375
    `BroadcastFunction` and the standalone `.op` syntax are available as of Julia 1.6.
1376
"""
1377
struct BroadcastFunction{F} <: Function
1378
    f::F
10✔
1379
end
1380

1381
@inline (op::BroadcastFunction)(x...; kwargs...) = op.f.(x...; kwargs...)
12✔
1382

1383
function Base.show(io::IO, op::BroadcastFunction)
1✔
1384
    print(io, BroadcastFunction, '(')
1✔
1385
    show(io, op.f)
1✔
1386
    print(io, ')')
1✔
1387
    nothing
1✔
1388
end
1389
Base.show(io::IO, ::MIME"text/plain", op::BroadcastFunction) = show(io, op)
×
1390

1391
end # module
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc