• 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

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

3
## array.jl: Dense arrays
4

5
"""
6
    DimensionMismatch([msg])
7

8
The objects called do not have matching dimensionality. Optional argument `msg` is a
9
descriptive error string.
10
"""
11
struct DimensionMismatch <: Exception
12
    msg::String
13,148✔
13
end
14
DimensionMismatch() = DimensionMismatch("")
8✔
15

16
## Type aliases for convenience ##
17
"""
18
    AbstractVector{T}
19

20
Supertype for one-dimensional arrays (or array-like types) with
21
elements of type `T`. Alias for [`AbstractArray{T,1}`](@ref).
22
"""
23
const AbstractVector{T} = AbstractArray{T,1}
24

25
"""
26
    AbstractMatrix{T}
27

28
Supertype for two-dimensional arrays (or array-like types) with
29
elements of type `T`. Alias for [`AbstractArray{T,2}`](@ref).
30
"""
31
const AbstractMatrix{T} = AbstractArray{T,2}
32

33
"""
34
    AbstractVecOrMat{T}
35

36
Union type of [`AbstractVector{T}`](@ref) and [`AbstractMatrix{T}`](@ref).
37
"""
38
const AbstractVecOrMat{T} = Union{AbstractVector{T}, AbstractMatrix{T}}
39
const RangeIndex = Union{<:BitInteger, AbstractRange{<:BitInteger}}
40
const DimOrInd = Union{Integer, AbstractUnitRange}
41
const IntOrInd = Union{Int, AbstractUnitRange}
42
const DimsOrInds{N} = NTuple{N,DimOrInd}
43
const NeedsShaping = Union{Tuple{Integer,Vararg{Integer}}, Tuple{OneTo,Vararg{OneTo}}}
44

45
"""
46
    Array{T,N} <: AbstractArray{T,N}
47

48
`N`-dimensional dense array with elements of type `T`.
49
"""
50
Array
51

52
"""
53
    Vector{T} <: AbstractVector{T}
54

55
One-dimensional dense array with elements of type `T`, often used to represent
56
a mathematical vector. Alias for [`Array{T,1}`](@ref).
57

58
See also [`empty`](@ref), [`similar`](@ref) and [`zero`](@ref) for creating vectors.
59
"""
60
const Vector{T} = Array{T,1}
61

62
"""
63
    Matrix{T} <: AbstractMatrix{T}
64

65
Two-dimensional dense array with elements of type `T`, often used to represent
66
a mathematical matrix. Alias for [`Array{T,2}`](@ref).
67

68
See also [`fill`](@ref), [`zeros`](@ref), [`undef`](@ref) and [`similar`](@ref)
69
for creating matrices.
70
"""
71
const Matrix{T} = Array{T,2}
72

73
"""
74
    VecOrMat{T}
75

76
Union type of [`Vector{T}`](@ref) and [`Matrix{T}`](@ref) which allows functions to accept either a Matrix or a Vector.
77

78
# Examples
79
```jldoctest
80
julia> Vector{Float64} <: VecOrMat{Float64}
81
true
82

83
julia> Matrix{Float64} <: VecOrMat{Float64}
84
true
85

86
julia> Array{Float64, 3} <: VecOrMat{Float64}
87
false
88
```
89
"""
90
const VecOrMat{T} = Union{Vector{T}, Matrix{T}}
91

92
"""
93
    DenseArray{T, N} <: AbstractArray{T,N}
94

95
`N`-dimensional dense array with elements of type `T`.
96
The elements of a dense array are stored contiguously in memory.
97
"""
98
DenseArray
99

100
"""
101
    DenseVector{T}
102

103
One-dimensional [`DenseArray`](@ref) with elements of type `T`. Alias for `DenseArray{T,1}`.
104
"""
105
const DenseVector{T} = DenseArray{T,1}
106

107
"""
108
    DenseMatrix{T}
109

110
Two-dimensional [`DenseArray`](@ref) with elements of type `T`. Alias for `DenseArray{T,2}`.
111
"""
112
const DenseMatrix{T} = DenseArray{T,2}
113

114
"""
115
    DenseVecOrMat{T}
116

117
Union type of [`DenseVector{T}`](@ref) and [`DenseMatrix{T}`](@ref).
118
"""
119
const DenseVecOrMat{T} = Union{DenseVector{T}, DenseMatrix{T}}
120

121
## Basic functions ##
122

123
using Core: arraysize, arrayset, const_arrayref
124

125
"""
126
    @_safeindex
127

128
This internal macro converts:
129
- `getindex(xs::Tuple, )` -> `__inbounds_getindex(args...)`
130
- `setindex!(xs::Vector, args...)` -> `__inbounds_setindex!(xs, args...)`
131
to tell the compiler that indexing operations within the applied expression are always
132
inbounds and do not need to taint `:consistent` and `:nothrow`.
133
"""
134
macro _safeindex(ex)
135
    return esc(_safeindex(__module__, ex))
136
end
137
function _safeindex(__module__, ex)
×
138
    isa(ex, Expr) || return ex
×
139
    if ex.head === :(=)
×
140
        lhs = arrayref(true, ex.args, 1)
×
141
        if isa(lhs, Expr) && lhs.head === :ref # xs[i] = x
×
142
            rhs = arrayref(true, ex.args, 2)
×
143
            xs = arrayref(true, lhs.args, 1)
×
144
            args = Vector{Any}(undef, length(lhs.args)-1)
×
145
            for i = 2:length(lhs.args)
×
146
                arrayset(true, args, _safeindex(__module__, arrayref(true, lhs.args, i)), i-1)
×
147
            end
×
148
            return Expr(:call, GlobalRef(__module__, :__inbounds_setindex!), xs, _safeindex(__module__, rhs), args...)
×
149
        end
150
    elseif ex.head === :ref # xs[i]
×
151
        return Expr(:call, GlobalRef(__module__, :__inbounds_getindex), ex.args...)
×
152
    end
153
    args = Vector{Any}(undef, length(ex.args))
×
154
    for i = 1:length(ex.args)
×
155
        arrayset(true, args, _safeindex(__module__, arrayref(true, ex.args, i)), i)
×
156
    end
×
157
    return Expr(ex.head, args...)
×
158
end
159

160
vect() = Vector{Any}()
21,913,189✔
161
function vect(X::T...) where T
131,030✔
162
    @_terminates_locally_meta
79,740✔
163
    vec = Vector{T}(undef, length(X))
1,173,892✔
164
    @_safeindex for i = 1:length(X)
1,188,266✔
165
        vec[i] = X[i]
1,358,711✔
166
    end
494,208✔
167
    return vec
1,173,892✔
168
end
169

170
"""
171
    vect(X...)
172

173
Create a [`Vector`](@ref) with element type computed from the `promote_typeof` of the argument,
174
containing the argument list.
175

176
# Examples
177
```jldoctest
178
julia> a = Base.vect(UInt8(1), 2.5, 1//2)
179
3-element Vector{Float64}:
180
 1.0
181
 2.5
182
 0.5
183
```
184
"""
185
function vect(X...)
2,513✔
186
    T = promote_typeof(X...)
2,513✔
187
    return T[X...]
2,742✔
188
end
189

190
size(a::Array, d::Integer) = arraysize(a, d isa Int ? d : convert(Int, d))
3,001,845✔
191
size(a::Vector) = (arraysize(a,1),)
4,398,867,277✔
192
size(a::Matrix) = (arraysize(a,1), arraysize(a,2))
7,122,403✔
193
size(a::Array{<:Any,N}) where {N} = (@inline; ntuple(M -> size(a, M), Val(N))::Dims)
2,724,564✔
194

195
asize_from(a::Array, n) = n > ndims(a) ? () : (arraysize(a,n), asize_from(a, n+1)...)
×
196

197
allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0))
2,809,539✔
198

199
"""
200
    Base.isbitsunion(::Type{T})
201

202
Return whether a type is an "is-bits" Union type, meaning each type included in a Union is [`isbitstype`](@ref).
203

204
# Examples
205
```jldoctest
206
julia> Base.isbitsunion(Union{Float64, UInt8})
207
true
208

209
julia> Base.isbitsunion(Union{Float64, String})
210
false
211
```
212
"""
213
isbitsunion(u::Union) = allocatedinline(u)
2,189✔
214
isbitsunion(x) = false
14,544✔
215

216
function _unsetindex!(A::Array{T}, i::Int) where {T}
73,168✔
217
    @inline
6,286✔
218
    @boundscheck checkbounds(A, i)
3,084,691✔
219
    t = @_gc_preserve_begin A
3,084,514✔
220
    p = Ptr{Ptr{Cvoid}}(pointer(A, i))
3,084,475✔
221
    if !allocatedinline(T)
6,286✔
222
        Intrinsics.atomic_pointerset(p, C_NULL, :monotonic)
2,835,399✔
223
    elseif T isa DataType
248,540✔
224
        if !datatype_pointerfree(T)
6,770✔
225
            for j = 1:Core.sizeof(Ptr{Cvoid}):Core.sizeof(T)
1,921✔
226
                Intrinsics.atomic_pointerset(p + j - 1, C_NULL, :monotonic)
5,373✔
227
            end
8,743✔
228
        end
229
    end
230
    @_gc_preserve_end t
3,083,796✔
231
    return A
3,083,274✔
232
end
233

234

235
"""
236
    Base.bitsunionsize(U::Union) -> Int
237

238
For a `Union` of [`isbitstype`](@ref) types, return the size of the largest type; assumes `Base.isbitsunion(U) == true`.
239

240
# Examples
241
```jldoctest
242
julia> Base.bitsunionsize(Union{Float64, UInt8})
243
8
244

245
julia> Base.bitsunionsize(Union{Float64, UInt8, Int128})
246
16
247
```
248
"""
249
function bitsunionsize(u::Union)
4✔
250
    isinline, sz, _ = uniontype_layout(u)
4✔
251
    @assert isinline
4✔
252
    return sz
4✔
253
end
254

255
# Deprecate this, as it seems to have no documented meaning and is unused here,
256
# but is frequently accessed in packages
257
elsize(@nospecialize _::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
1,802,652✔
258
elsize(::Type{Union{}}, slurp...) = 0
×
259
sizeof(a::Array) = Core.sizeof(a)
3,410,531✔
260

261
function isassigned(a::Array, i::Int...)
3,600,277✔
262
    @inline
2,542,644✔
263
    @boundscheck checkbounds(Bool, a, i...) || return false
2,070,416,391✔
264
    ii = (_sub2ind(size(a), i...) % UInt) - 1
2,013,838,964✔
265
    ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii) == 1
2,070,051,189✔
266
end
267

268
## copy ##
269

270
"""
271
    unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
272

273
Copy `N` elements from a source pointer to a destination, with no checking. The size of an
274
element is determined by the type of the pointers.
275

276
The `unsafe` prefix on this function indicates that no validation is performed on the
277
pointers `dest` and `src` to ensure that they are valid. Incorrect usage may corrupt or
278
segfault your program, in the same manner as C.
279
"""
280
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
8,182,642✔
281
    # Do not use this to copy data between pointer arrays.
282
    # It can't be made safe no matter how carefully you checked.
283
    ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
23,618,765✔
284
          dest, src, n * aligned_sizeof(T))
285
    return dest
22,816,398✔
286
end
287

288

289
function _unsafe_copyto!(dest, doffs, src, soffs, n)
24,320,784✔
290
    destp = pointer(dest, doffs)
24,320,784✔
291
    srcp = pointer(src, soffs)
24,320,784✔
292
    @inbounds if destp < srcp || destp > srcp + n
41,017,969✔
293
        for i = 1:n
48,641,566✔
294
            if isassigned(src, soffs + i - 1)
133,560,636✔
295
                dest[doffs + i - 1] = src[soffs + i - 1]
133,560,080✔
296
            else
297
                _unsetindex!(dest, doffs + i - 1)
720✔
298
            end
299
        end
242,800,249✔
300
    else
301
        for i = n:-1:1
×
302
            if isassigned(src, soffs + i - 1)
×
303
                dest[doffs + i - 1] = src[soffs + i - 1]
×
304
            else
305
                _unsetindex!(dest, doffs + i - 1)
×
306
            end
307
        end
×
308
    end
309
    return dest
24,320,543✔
310
end
311

312
"""
313
    unsafe_copyto!(dest::Array, do, src::Array, so, N)
314

315
Copy `N` elements from a source array to a destination, starting at the linear index `so` in the
316
source and `do` in the destination (1-indexed).
317

318
The `unsafe` prefix on this function indicates that no validation is performed to ensure
319
that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
320
the same manner as C.
321
"""
322
function unsafe_copyto!(dest::Array{T}, doffs, src::Array{T}, soffs, n) where T
3,956,690✔
323
    t1 = @_gc_preserve_begin dest
123,233,467✔
324
    t2 = @_gc_preserve_begin src
123,233,467✔
325
    destp = pointer(dest, doffs)
123,233,467✔
326
    srcp = pointer(src, soffs)
123,233,478✔
327
    if !allocatedinline(T)
3,954,003✔
328
        ccall(:jl_array_ptr_copy, Cvoid, (Any, Ptr{Cvoid}, Any, Ptr{Cvoid}, Int),
64,226,290✔
329
              dest, destp, src, srcp, n)
330
    elseif isbitstype(T)
1,930,933✔
331
        ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
39,735,860✔
332
              destp, srcp, n * aligned_sizeof(T))
333
    elseif isbitsunion(T)
7,059✔
334
        ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
953✔
335
              destp, srcp, n * aligned_sizeof(T))
336
        # copy selector bytes
337
        ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
953✔
338
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), dest) + doffs - 1,
339
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), src) + soffs - 1,
340
              n)
341
    else
342
        _unsafe_copyto!(dest, doffs, src, soffs, n)
19,270,375✔
343
    end
344
    @_gc_preserve_end t2
123,233,467✔
345
    @_gc_preserve_end t1
123,233,467✔
346
    return dest
41,765,827✔
347
end
348

349
unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n) =
5,050,409✔
350
    _unsafe_copyto!(dest, doffs, src, soffs, n)
351

352
"""
353
    copyto!(dest, do, src, so, N)
354

355
Copy `N` elements from collection `src` starting at the linear index `so`, to array `dest` starting at
356
the index `do`. Return `dest`.
357
"""
358
function copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
34,055✔
359
    return _copyto_impl!(dest, doffs, src, soffs, n)
10,101,475✔
360
end
361

362
# this is only needed to avoid possible ambiguities with methods added in some packages
363
function copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where T
1,043,378✔
364
    return _copyto_impl!(dest, doffs, src, soffs, n)
147,440,594✔
365
end
366

367
function _copyto_impl!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
147,473,099✔
368
    n == 0 && return dest
152,490,110✔
369
    n > 0 || _throw_argerror("Number of elements to copy must be nonnegative.")
123,570,922✔
370
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
123,570,941✔
371
    @boundscheck checkbounds(src, soffs:soffs+n-1)
123,570,902✔
372
    unsafe_copyto!(dest, doffs, src, soffs, n)
123,570,896✔
373
    return dest
123,570,655✔
374
end
375

376
# Outlining this because otherwise a catastrophic inference slowdown
377
# occurs, see discussion in #27874.
378
# It is also mitigated by using a constant string.
379
_throw_argerror(s) = (@noinline; throw(ArgumentError(s)))
3,908✔
380

381
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
10,096,607✔
382

383
# also to avoid ambiguities in packages
384
copyto!(dest::Array{T}, src::Array{T}) where {T} = copyto!(dest, 1, src, 1, length(src))
40,264,459✔
385

386
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
387
# for bootstrapping purposes.
388
function fill!(dest::Array{T}, x) where T
98,812✔
389
    xT = x isa T ? x : convert(T, x)::T
98,771✔
390
    for i in eachindex(dest)
655,339,013✔
391
        @inbounds dest[i] = xT
5,065,028,825✔
392
    end
9,953,035,062✔
393
    return dest
478,316,425✔
394
end
395

396
"""
397
    copy(x)
398

399
Create a shallow copy of `x`: the outer structure is copied, but not all internal values.
400
For example, copying an array produces a new array with identically-same elements as the
401
original.
402

403
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
404
"""
405
copy
406

407
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
134,784,630✔
408

409
## Constructors ##
410

411
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
4,872✔
412
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
3,982✔
413
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
8,787✔
414
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
16,580✔
415
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
1,691,930✔
416
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
56,084,524✔
417
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
386✔
418

419
# T[x...] constructs Array{T,1}
420
"""
421
    getindex(type[, elements...])
422

423
Construct a 1-d array of the specified type. This is usually called with the syntax
424
`Type[]`. Element values can be specified using `Type[a,b,c,...]`.
425

426
# Examples
427
```jldoctest
428
julia> Int8[1, 2, 3]
429
3-element Vector{Int8}:
430
 1
431
 2
432
 3
433

434
julia> getindex(Int8, 1, 2, 3)
435
3-element Vector{Int8}:
436
 1
437
 2
438
 3
439
```
440
"""
441
function getindex(::Type{T}, vals...) where T
183,687✔
442
    @inline
50,303✔
443
    @_effect_free_terminates_locally_meta
50,303✔
444
    a = Vector{T}(undef, length(vals))
625,194,134✔
445
    if vals isa NTuple
50,450✔
446
        @_safeindex for i in 1:length(vals)
22,069,766✔
447
            a[i] = vals[i]
22,117,904✔
448
        end
171,551✔
449
    else
450
        # use afoldl to avoid type instability inside loop
451
        afoldl(1, vals...) do i, v
4,034✔
452
            @inbounds a[i] = v
12,031✔
453
            return i + 1
10,760✔
454
        end
455
    end
456
    return a
22,070,253✔
457
end
458

459
function getindex(::Type{Any}, @nospecialize vals...)
20,796,221✔
460
    @_effect_free_terminates_locally_meta
16,841✔
461
    a = Vector{Any}(undef, length(vals))
47,442,106✔
462
    @_safeindex for i = 1:length(vals)
62,694,184✔
463
        a[i] = vals[i]
89,425,184✔
464
    end
104,632,070✔
465
    return a
47,442,106✔
466
end
467
getindex(::Type{Any}) = Vector{Any}()
30,229,469✔
468

469
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
7,458✔
470
    ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), a, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
142,306,675✔
471
    return a
142,306,669✔
472
end
473

474
to_dim(d::Integer) = d
×
475
to_dim(d::OneTo) = last(d)
376✔
476

477
"""
478
    fill(value, dims::Tuple)
479
    fill(value, dims...)
480

481
Create an array of size `dims` with every location set to `value`.
482

483
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
484
with `1.0` in every location of the array.
485

486
The dimension lengths `dims` may be specified as either a tuple or a sequence of arguments.
487
An `N`-length tuple or `N` arguments following the `value` specify an `N`-dimensional
488
array. Thus, a common idiom for creating a zero-dimensional array with its only location
489
set to `x` is `fill(x)`.
490

491
Every location of the returned array is set to (and is thus [`===`](@ref) to)
492
the `value` that was passed; this means that if the `value` is itself modified,
493
all elements of the `fill`ed array will reflect that modification because they're
494
_still_ that very `value`. This is of no concern with `fill(1.0, (5,5))` as the
495
`value` `1.0` is immutable and cannot itself be modified, but can be unexpected
496
with mutable values like — most commonly — arrays.  For example, `fill([], 3)`
497
places _the very same_ empty array in all three locations of the returned vector:
498

499
```jldoctest
500
julia> v = fill([], 3)
501
3-element Vector{Vector{Any}}:
502
 []
503
 []
504
 []
505

506
julia> v[1] === v[2] === v[3]
507
true
508

509
julia> value = v[1]
510
Any[]
511

512
julia> push!(value, 867_5309)
513
1-element Vector{Any}:
514
 8675309
515

516
julia> v
517
3-element Vector{Vector{Any}}:
518
 [8675309]
519
 [8675309]
520
 [8675309]
521
```
522

523
To create an array of many independent inner arrays, use a [comprehension](@ref man-comprehensions) instead.
524
This creates a new and distinct array on each iteration of the loop:
525

526
```jldoctest
527
julia> v2 = [[] for _ in 1:3]
528
3-element Vector{Vector{Any}}:
529
 []
530
 []
531
 []
532

533
julia> v2[1] === v2[2] === v2[3]
534
false
535

536
julia> push!(v2[1], 8675309)
537
1-element Vector{Any}:
538
 8675309
539

540
julia> v2
541
3-element Vector{Vector{Any}}:
542
 [8675309]
543
 []
544
 []
545
```
546

547
See also: [`fill!`](@ref), [`zeros`](@ref), [`ones`](@ref), [`similar`](@ref).
548

549
# Examples
550
```jldoctest
551
julia> fill(1.0, (2,3))
552
2×3 Matrix{Float64}:
553
 1.0  1.0  1.0
554
 1.0  1.0  1.0
555

556
julia> fill(42)
557
0-dimensional Array{Int64, 0}:
558
42
559

560
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
561
2-element Vector{Vector{Float64}}:
562
 [0.0, 0.0]
563
 [0.0, 0.0]
564

565
julia> A[1][1] = 42; # modifies the filled value to be [42.0, 0.0]
566

567
julia> A # both A[1] and A[2] are the very same vector
568
2-element Vector{Vector{Float64}}:
569
 [42.0, 0.0]
570
 [42.0, 0.0]
571
```
572
"""
573
function fill end
574

575
fill(v, dims::DimOrInd...) = fill(v, dims)
3,456,881,502✔
576
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
577
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
4,305,509,332✔
578
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
387✔
579

580
"""
581
    zeros([T=Float64,] dims::Tuple)
582
    zeros([T=Float64,] dims...)
583

584
Create an `Array`, with element type `T`, of all zeros with size specified by `dims`.
585
See also [`fill`](@ref), [`ones`](@ref), [`zero`](@ref).
586

587
# Examples
588
```jldoctest
589
julia> zeros(1)
590
1-element Vector{Float64}:
591
 0.0
592

593
julia> zeros(Int8, 2, 3)
594
2×3 Matrix{Int8}:
595
 0  0  0
596
 0  0  0
597
```
598
"""
599
function zeros end
600

601
"""
602
    ones([T=Float64,] dims::Tuple)
603
    ones([T=Float64,] dims...)
604

605
Create an `Array`, with element type `T`, of all ones with size specified by `dims`.
606
See also [`fill`](@ref), [`zeros`](@ref).
607

608
# Examples
609
```jldoctest
610
julia> ones(1,2)
611
1×2 Matrix{Float64}:
612
 1.0  1.0
613

614
julia> ones(ComplexF64, 2, 3)
615
2×3 Matrix{ComplexF64}:
616
 1.0+0.0im  1.0+0.0im  1.0+0.0im
617
 1.0+0.0im  1.0+0.0im  1.0+0.0im
618
```
619
"""
620
function ones end
621

622
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
623
    @eval begin
624
        $fname(dims::DimOrInd...) = $fname(dims)
20,447,027✔
625
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
173,990,992✔
626
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,481,425✔
627
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,625✔
628
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
46,102✔
629
            a = Array{T,N}(undef, dims)
51,634,549✔
630
            fill!(a, $felt(T))
598,689,854✔
631
            return a
51,634,549✔
632
        end
633
        function $fname(::Type{T}, dims::Tuple{}) where {T}
16✔
634
            a = Array{T}(undef)
16✔
635
            fill!(a, $felt(T))
16✔
636
            return a
16✔
637
        end
638
    end
639
end
640

641
function _one(unit::T, x::AbstractMatrix) where T
140✔
642
    require_one_based_indexing(x)
140✔
643
    m,n = size(x)
140✔
644
    m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
140✔
645
    # Matrix{T}(I, m, m)
646
    I = zeros(T, m, m)
3,693✔
647
    for i in 1:m
280✔
648
        I[i,i] = unit
613✔
649
    end
1,086✔
650
    I
140✔
651
end
652

653
one(x::AbstractMatrix{T}) where {T} = _one(one(T), x)
127✔
654
oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)
19✔
655

656
## Conversions ##
657

658
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
25,525✔
659

660
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
50✔
661

662
## Constructors ##
663

664
if nameof(@__MODULE__) === :Base  # avoid method overwrite
665
# constructors should make copies
666
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
28,796✔
667
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
26,055✔
668
end
669

670
## copying iterators to containers
671

672
"""
673
    collect(element_type, collection)
674

675
Return an `Array` with the given element type of all items in a collection or iterable.
676
The result has the same shape and number of dimensions as `collection`.
677

678
# Examples
679
```jldoctest
680
julia> collect(Float64, 1:2:5)
681
3-element Vector{Float64}:
682
 1.0
683
 3.0
684
 5.0
685
```
686
"""
687
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
21,106,351✔
688

689
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
10,033,134✔
690
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
691
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
11,073,215✔
692
    a = Vector{T}()
11,073,215✔
693
    for x in itr
17,130,389✔
694
        push!(a, x)
7,554,671✔
695
    end
9,052,167✔
696
    return a
11,073,215✔
697
end
698

699
# make a collection similar to `c` and appropriate for collecting `itr`
700
_similar_for(c, ::Type{T}, itr, isz, shp) where {T} = similar(c, T)
×
701

702
_similar_shape(itr, ::SizeUnknown) = nothing
1✔
703
_similar_shape(itr, ::HasLength) = length(itr)::Integer
33,668,653✔
704
_similar_shape(itr, ::HasShape) = axes(itr)
404,567,841✔
705

706
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,011,353✔
707
    similar(c, T, 0)
708
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
3,522,979✔
709
    similar(c, T, len)
710
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
42,459✔
711
    similar(c, T, axs)
712

713
# make a collection appropriate for collecting `itr::Generator`
714
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
331✔
715
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
27,455,665✔
716
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
404,724,713✔
717

718
# used by syntax lowering for simple typed comprehensions
719
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
429,144,503✔
720

721

722
"""
723
    collect(collection)
724

725
Return an `Array` of all items in a collection or iterator. For dictionaries, returns
726
`Pair{KeyType, ValType}`. If the argument is array-like or is an iterator with the
727
[`HasShape`](@ref IteratorSize) trait, the result will have the same shape
728
and number of dimensions as the argument.
729

730
Used by comprehensions to turn a generator into an `Array`.
731

732
# Examples
733
```jldoctest
734
julia> collect(1:2:13)
735
7-element Vector{Int64}:
736
  1
737
  3
738
  5
739
  7
740
  9
741
 11
742
 13
743

744
julia> [x^2 for x in 1:8 if isodd(x)]
745
4-element Vector{Int64}:
746
  1
747
  9
748
 25
749
 49
750
```
751
"""
752
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
4,758,466✔
753

754
collect(A::AbstractArray) = _collect_indices(axes(A), A)
139,735✔
755

756
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
41,848✔
757

758
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
3,747,242✔
759
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
760

761
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,011,320✔
762
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,011,323✔
763
    for x in itr
2,021,675✔
764
        push!(a,x)
8,678,297✔
765
    end
14,743,461✔
766
    return a
1,011,319✔
767
end
768

769
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
25✔
770
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
184,702✔
771
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
772
function _collect_indices(indsA, A)
115✔
773
    B = Array{eltype(A)}(undef, length.(indsA))
115✔
774
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
115✔
775
end
776

777
# NOTE: this function is not meant to be called, only inferred, for the
778
# purpose of bounding the types of values generated by an iterator.
779
function _iterator_upper_bound(itr)
6✔
780
    x = iterate(itr)
×
781
    while x !== nothing
×
782
        val = getfield(x, 1)
×
783
        if inferencebarrier(nothing)
×
784
            return val
×
785
        end
786
        x = iterate(itr, getfield(x, 2))
×
787
    end
×
788
    throw(nothing)
6✔
789
end
790

791
# define this as a macro so that the call to Core.Compiler
792
# gets inlined into the caller before recursion detection
793
# gets a chance to see it, so that recursive calls to the caller
794
# don't trigger the inference limiter
795
if isdefined(Core, :Compiler)
796
    macro default_eltype(itr)
1✔
797
        I = esc(itr)
1✔
798
        return quote
1✔
799
            if $I isa Generator && ($I).f isa Type
614,519✔
800
                T = ($I).f
687✔
801
            else
802
                T = Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)})
99,835✔
803
            end
804
            promote_typejoin_union(T)
100,522✔
805
        end
806
    end
807
else
808
    macro default_eltype(itr)
809
        I = esc(itr)
810
        return quote
811
            if $I isa Generator && ($I).f isa Type
812
                promote_typejoin_union($I.f)
813
            else
814
                Any
815
            end
816
        end
817
    end
818
end
819

820
function collect(itr::Generator)
571,073✔
821
    isz = IteratorSize(itr.iter)
69,056✔
822
    et = @default_eltype(itr)
×
823
    if isa(isz, SizeUnknown)
69,056✔
824
        return grow_to!(Vector{et}(), itr)
83,128✔
825
    else
826
        shp = _similar_shape(itr, isz)
488,336✔
827
        y = iterate(itr)
965,949✔
828
        if y === nothing
488,318✔
829
            return _array_for(et, isz, shp)
465✔
830
        end
831
        v1, st = y
67,722✔
832
        dest = _array_for(typeof(v1), isz, shp)
488,001✔
833
        # The typeassert gives inference a helping hand on the element type and dimensionality
834
        # (work-around for #28382)
835
        et′ = et <: Type ? Type : et
67,722✔
836
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
67,813✔
837
        collect_to_with_first!(dest, v1, itr, st)::RT
10,481,904✔
838
    end
839
end
840

841
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
33✔
842
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
843

844
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
41,310✔
845
    et = @default_eltype(itr)
29,917✔
846
    shp = _similar_shape(itr, isz)
41,310✔
847
    y = iterate(itr)
82,059✔
848
    if y === nothing
41,309✔
849
        return _similar_for(c, et, itr, isz, shp)
173✔
850
    end
851
    v1, st = y
29,915✔
852
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
41,152✔
853
    # The typeassert gives inference a helping hand on the element type and dimensionality
854
    # (work-around for #28382)
855
    et′ = et <: Type ? Type : et
29,867✔
856
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
29,886✔
857
    collect_to_with_first!(dest, v1, itr, st)::RT
41,702✔
858
end
859

860
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
97,655✔
861
    i1 = first(LinearIndices(dest))
97,589✔
862
    dest[i1] = v1
529,035✔
863
    return collect_to!(dest, itr, i1+1, st)
82,713,887✔
864
end
865

866
function collect_to_with_first!(dest, v1, itr, st)
×
867
    push!(dest, v1)
×
868
    return grow_to!(dest, itr, st)
×
869
end
870

871
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
399✔
872
    @inline
396✔
873
    new = similar(dest, promote_typejoin(T, typeof(el)))
403✔
874
    f = first(LinearIndices(dest))
396✔
875
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
793✔
876
    @inbounds new[i] = el
399✔
877
    return new
399✔
878
end
879

880
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
133,664✔
881
    # collect to dest array, checking the type of each result. if a result does not
882
    # match, widen the result type and re-dispatch.
883
    i = offs
97,988✔
884
    while true
86,978,817✔
885
        y = iterate(itr, st)
173,427,209✔
886
        y === nothing && break
86,978,809✔
887
        el, st = y
86,156,911✔
888
        if el isa T
86,155,524✔
889
            @inbounds dest[i] = el
86,456,033✔
890
            i += 1
86,449,383✔
891
        else
892
            new = setindex_widen_up_to(dest, el, i)
523✔
893
            return collect_to!(new, itr, i+1, st)
399✔
894
        end
895
    end
86,449,383✔
896
    return dest
529,027✔
897
end
898

899
function grow_to!(dest, itr)
1,117✔
900
    y = iterate(itr)
1,361✔
901
    y === nothing && return dest
1,117✔
902
    dest2 = empty(dest, typeof(y[1]))
265✔
903
    push!(dest2, y[1])
288✔
904
    grow_to!(dest2, itr, y[2])
249✔
905
end
906

907
function push_widen(dest, el)
53✔
908
    @inline
53✔
909
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
53✔
910
    if new isa AbstractSet
53✔
911
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
912
        union!(new, dest)
1✔
913
    else
914
        append!(new, dest)
104✔
915
    end
916
    push!(new, el)
53✔
917
    return new
53✔
918
end
919

920
function grow_to!(dest, itr, st)
302✔
921
    T = eltype(dest)
199✔
922
    y = iterate(itr, st)
552✔
923
    while y !== nothing
3,290✔
924
        el, st = y
1,741✔
925
        if el isa T
1,741✔
926
            push!(dest, el)
2,991✔
927
        else
928
            new = push_widen(dest, el)
55✔
929
            return grow_to!(new, itr, st)
53✔
930
        end
931
        y = iterate(itr, st)
4,627✔
932
    end
2,988✔
933
    return dest
249✔
934
end
935

936
## Iteration ##
937

938
iterate(A::Array, i=1) = (@inline; (i % UInt) - 1 < length(A) ? (@inbounds A[i], i + 1) : nothing)
8,959,037,874✔
939

940
## Indexing: getindex ##
941

942
"""
943
    getindex(collection, key...)
944

945
Retrieve the value(s) stored at the given key or index within a collection. The syntax
946
`a[i,j,...]` is converted by the compiler to `getindex(a, i, j, ...)`.
947

948
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
949

950
# Examples
951
```jldoctest
952
julia> A = Dict("a" => 1, "b" => 2)
953
Dict{String, Int64} with 2 entries:
954
  "b" => 2
955
  "a" => 1
956

957
julia> getindex(A, "a")
958
1
959
```
960
"""
961
function getindex end
962

963
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
964
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
1,073,914✔
965
    @inline
794,298✔
966
    @boundscheck checkbounds(A, I)
55,795,024✔
967
    lI = length(I)
55,795,024✔
968
    X = similar(A, axes(I))
55,795,036✔
969
    if lI > 0
55,795,024✔
970
        copyto!(X, firstindex(X), A, first(I), lI)
49,967,430✔
971
    end
972
    return X
55,795,024✔
973
end
974

975
# getindex for carrying out logical indexing for AbstractUnitRange{Bool} as Bool <: Integer
976
getindex(a::Array, r::AbstractUnitRange{Bool}) = getindex(a, to_index(r))
21✔
977

978
function getindex(A::Array, c::Colon)
4,813✔
979
    lI = length(A)
1,687,834✔
980
    X = similar(A, lI)
1,687,834✔
981
    if lI > 0
1,687,834✔
982
        unsafe_copyto!(X, 1, A, 1, lI)
1,687,832✔
983
    end
984
    return X
1,687,834✔
985
end
986

987
# This is redundant with the abstract fallbacks, but needed for bootstrap
988
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
3,168,330✔
989
    return S[ A[i] for i in I ]
13,046,738✔
990
end
991

992
## Indexing: setindex! ##
993

994
"""
995
    setindex!(collection, value, key...)
996

997
Store the given value at the given key or index within a collection. The syntax `a[i,j,...] =
998
x` is converted by the compiler to `(setindex!(a, x, i, j, ...); x)`.
999

1000
# Examples
1001
```jldoctest
1002
julia> a = Dict("a"=>1)
1003
Dict{String, Int64} with 1 entry:
1004
  "a" => 1
1005

1006
julia> setindex!(a, 2, "b")
1007
Dict{String, Int64} with 2 entries:
1008
  "b" => 2
1009
  "a" => 1
1010
```
1011
"""
1012
function setindex! end
1013

1014
@eval setindex!(A::Array{T}, x, i1::Int) where {T} =
17,481,826,679✔
1015
    arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1)
1016
@eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
54,677,342✔
1017
    (@inline; arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1, i2, I...))
56,484,428✔
1018

1019
__inbounds_setindex!(A::Array{T}, x, i1::Int) where {T} =
1,242,243,302✔
1020
    arrayset(false, A, convert(T,x)::T, i1)
1021
__inbounds_setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
×
1022
    (@inline; arrayset(false, A, convert(T,x)::T, i1, i2, I...))
×
1023

1024
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1025
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
800,479✔
1026
    @_propagate_inbounds_meta
800,479✔
1027
    @boundscheck setindex_shape_check(X, length(I))
5,914,584✔
1028
    require_one_based_indexing(X)
800,479✔
1029
    X′ = unalias(A, X)
805,806✔
1030
    I′ = unalias(A, I)
800,907✔
1031
    count = 1
800,479✔
1032
    for i in I′
11,048,096✔
1033
        @inbounds x = X′[count]
14,680,963✔
1034
        A[i] = x
14,683,046✔
1035
        count += 1
14,680,963✔
1036
    end
24,181,626✔
1037
    return A
5,914,584✔
1038
end
1039

1040
# Faster contiguous setindex! with copyto!
1041
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
1,008,018✔
1042
    @inline
1,007,996✔
1043
    @boundscheck checkbounds(A, I)
1,008,370✔
1044
    lI = length(I)
1,008,370✔
1045
    @boundscheck setindex_shape_check(X, lI)
1,008,370✔
1046
    if lI > 0
1,008,370✔
1047
        unsafe_copyto!(A, first(I), X, 1, lI)
1,008,263✔
1048
    end
1049
    return A
1,008,370✔
1050
end
1051
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
47✔
1052
    @inline
47✔
1053
    lI = length(A)
47✔
1054
    @boundscheck setindex_shape_check(X, lI)
47✔
1055
    if lI > 0
47✔
1056
        unsafe_copyto!(A, 1, X, 1, lI)
47✔
1057
    end
1058
    return A
47✔
1059
end
1060

1061
# efficiently grow an array
1062

1063
_growbeg!(a::Vector, delta::Integer) =
1,054,061✔
1064
    ccall(:jl_array_grow_beg, Cvoid, (Any, UInt), a, delta)
1065
_growend!(a::Vector, delta::Integer) =
1,527,482,780✔
1066
    ccall(:jl_array_grow_end, Cvoid, (Any, UInt), a, delta)
1067
_growat!(a::Vector, i::Integer, delta::Integer) =
66,310,737✔
1068
    ccall(:jl_array_grow_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1069

1070
# efficiently delete part of an array
1071

1072
_deletebeg!(a::Vector, delta::Integer) =
19,196,776✔
1073
    ccall(:jl_array_del_beg, Cvoid, (Any, UInt), a, delta)
1074
_deleteend!(a::Vector, delta::Integer) =
596,808,973✔
1075
    ccall(:jl_array_del_end, Cvoid, (Any, UInt), a, delta)
1076
_deleteat!(a::Vector, i::Integer, delta::Integer) =
219,773✔
1077
    ccall(:jl_array_del_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1078

1079
## Dequeue functionality ##
1080

1081
"""
1082
    push!(collection, items...) -> collection
1083

1084
Insert one or more `items` in `collection`. If `collection` is an ordered container,
1085
the items are inserted at the end (in the given order).
1086

1087
# Examples
1088
```jldoctest
1089
julia> push!([1, 2, 3], 4, 5, 6)
1090
6-element Vector{Int64}:
1091
 1
1092
 2
1093
 3
1094
 4
1095
 5
1096
 6
1097
```
1098

1099
If `collection` is ordered, use [`append!`](@ref) to add all the elements of another
1100
collection to it. The result of the preceding example is equivalent to `append!([1, 2, 3], [4,
1101
5, 6])`. For `AbstractSet` objects, [`union!`](@ref) can be used instead.
1102

1103
See [`sizehint!`](@ref) for notes about the performance model.
1104

1105
See also [`pushfirst!`](@ref).
1106
"""
1107
function push! end
1108

1109
function push!(a::Vector{T}, item) where T
340,424✔
1110
    # convert first so we don't grow the array if the assignment won't work
1111
    itemT = item isa T ? item : convert(T, item)::T
24,349,613✔
1112
    _growend!(a, 1)
1,016,561,826✔
1113
    @_safeindex a[length(a)] = itemT
1,016,561,826✔
1114
    return a
10,068,663✔
1115
end
1116

1117
# specialize and optimize the single argument case
1118
function push!(a::Vector{Any}, @nospecialize x)
3,138,230✔
1119
    _growend!(a, 1)
86,685,902✔
1120
    @_safeindex a[length(a)] = x
86,685,902✔
1121
    return a
2,894,050✔
1122
end
1123
function push!(a::Vector{Any}, @nospecialize x...)
94,335✔
1124
    @_terminates_locally_meta
2✔
1125
    na = length(a)
94,335✔
1126
    nx = length(x)
2✔
1127
    _growend!(a, nx)
94,335✔
1128
    @_safeindex for i = 1:nx
94,335✔
1129
        a[na+i] = x[i]
192,798✔
1130
    end
283,009✔
1131
    return a
94,335✔
1132
end
1133

1134
"""
1135
    append!(collection, collections...) -> collection.
1136

1137
For an ordered container `collection`, add the elements of each `collections`
1138
to the end of it.
1139

1140
!!! compat "Julia 1.6"
1141
    Specifying multiple collections to be appended requires at least Julia 1.6.
1142

1143
# Examples
1144
```jldoctest
1145
julia> append!([1], [2, 3])
1146
3-element Vector{Int64}:
1147
 1
1148
 2
1149
 3
1150

1151
julia> append!([1, 2, 3], [4, 5], [6])
1152
6-element Vector{Int64}:
1153
 1
1154
 2
1155
 3
1156
 4
1157
 5
1158
 6
1159
```
1160

1161
Use [`push!`](@ref) to add individual items to `collection` which are not already
1162
themselves in another collection. The result of the preceding example is equivalent to
1163
`push!([1, 2, 3], 4, 5, 6)`.
1164

1165
See [`sizehint!`](@ref) for notes about the performance model.
1166

1167
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1168
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1169
"""
1170
function append!(a::Vector, items::AbstractVector)
65,419✔
1171
    itemindices = eachindex(items)
56,777,770✔
1172
    n = length(itemindices)
35,261✔
1173
    _growend!(a, n)
56,777,770✔
1174
    copyto!(a, length(a)-n+1, items, first(itemindices), n)
56,779,096✔
1175
    return a
56,777,770✔
1176
end
1177

1178
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
46,649,047✔
1179
push!(a::AbstractVector, iter...) = append!(a, iter)
3,967✔
1180

1181
append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
77✔
1182

1183
function _append!(a, ::Union{HasLength,HasShape}, iter)
16,677,619✔
1184
    @_terminates_locally_meta
1,912✔
1185
    n = length(a)
16,677,619✔
1186
    i = lastindex(a)
16,677,619✔
1187
    resize!(a, n+Int(length(iter))::Int)
27,203,298✔
1188
    @_safeindex for (i, item) in zip(i+1:lastindex(a), iter)
22,829,559✔
1189
        a[i] = item
25,101,277✔
1190
    end
44,047,034✔
1191
    a
16,677,619✔
1192
end
1193

1194
function _append!(a, ::IteratorSize, iter)
29,971,427✔
1195
    for item in iter
29,971,429✔
1196
        push!(a, item)
30,029,187✔
1197
    end
30,029,192✔
1198
    a
29,971,427✔
1199
end
1200

1201
"""
1202
    prepend!(a::Vector, collections...) -> collection
1203

1204
Insert the elements of each `collections` to the beginning of `a`.
1205

1206
When `collections` specifies multiple collections, order is maintained:
1207
elements of `collections[1]` will appear leftmost in `a`, and so on.
1208

1209
!!! compat "Julia 1.6"
1210
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1211

1212
# Examples
1213
```jldoctest
1214
julia> prepend!([3], [1, 2])
1215
3-element Vector{Int64}:
1216
 1
1217
 2
1218
 3
1219

1220
julia> prepend!([6], [1, 2], [3, 4, 5])
1221
6-element Vector{Int64}:
1222
 1
1223
 2
1224
 3
1225
 4
1226
 5
1227
 6
1228
```
1229
"""
1230
function prepend! end
1231

1232
function prepend!(a::Vector, items::AbstractVector)
459✔
1233
    itemindices = eachindex(items)
459✔
1234
    n = length(itemindices)
459✔
1235
    _growbeg!(a, n)
459✔
1236
    if a === items
459✔
1237
        copyto!(a, 1, items, n+1, n)
1✔
1238
    else
1239
        copyto!(a, 1, items, first(itemindices), n)
612✔
1240
    end
1241
    return a
459✔
1242
end
1243

1244
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
13✔
1245
pushfirst!(a::Vector, iter...) = prepend!(a, iter)
7✔
1246

1247
prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
7✔
1248

1249
function _prepend!(a, ::Union{HasLength,HasShape}, iter)
7✔
1250
    @_terminates_locally_meta
7✔
1251
    require_one_based_indexing(a)
7✔
1252
    n = length(iter)
7✔
1253
    _growbeg!(a, n)
7✔
1254
    i = 0
7✔
1255
    for item in iter
7✔
1256
        @_safeindex a[i += 1] = item
13✔
1257
    end
18✔
1258
    a
7✔
1259
end
1260
function _prepend!(a, ::IteratorSize, iter)
2✔
1261
    n = 0
2✔
1262
    for item in iter
3✔
1263
        n += 1
5✔
1264
        pushfirst!(a, item)
5✔
1265
    end
9✔
1266
    reverse!(a, 1, n)
2✔
1267
    a
2✔
1268
end
1269

1270
"""
1271
    resize!(a::Vector, n::Integer) -> Vector
1272

1273
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1274
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1275
guaranteed to be initialized.
1276

1277
# Examples
1278
```jldoctest
1279
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1280
3-element Vector{Int64}:
1281
 6
1282
 5
1283
 4
1284

1285
julia> a = resize!([6, 5, 4, 3, 2, 1], 8);
1286

1287
julia> length(a)
1288
8
1289

1290
julia> a[1:6]
1291
6-element Vector{Int64}:
1292
 6
1293
 5
1294
 4
1295
 3
1296
 2
1297
 1
1298
```
1299
"""
1300
function resize!(a::Vector, nl::Integer)
5,603,944✔
1301
    l = length(a)
719,988,847✔
1302
    if nl > l
719,988,847✔
1303
        _growend!(a, nl-l)
251,935,790✔
1304
    elseif nl != l
468,053,059✔
1305
        if nl < 0
64,314,574✔
1306
            _throw_argerror("new length must be ≥ 0")
2✔
1307
        end
1308
        _deleteend!(a, l-nl)
239,321,250✔
1309
    end
1310
    return a
719,988,845✔
1311
end
1312

1313
"""
1314
    sizehint!(s, n) -> s
1315

1316
Suggest that collection `s` reserve capacity for at least `n` elements. That is, if
1317
you expect that you're going to have to push a lot of values onto `s`, you can avoid
1318
the cost of incremental reallocation by doing it once up front; this can improve
1319
performance.
1320

1321
See also [`resize!`](@ref).
1322

1323
# Notes on the performance model
1324

1325
For types that support `sizehint!`,
1326

1327
1. `push!` and `append!` methods generally may (but are not required to) preallocate extra
1328
   storage. For types implemented in `Base`, they typically do, using a heuristic optimized for
1329
   a general use case.
1330

1331
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1332
   `Base`.
1333

1334
3. `empty!` is nearly costless (and O(1)) for types that support this kind of preallocation.
1335
"""
1336
function sizehint! end
1337

1338
function sizehint!(a::Vector, sz::Integer)
458,442✔
1339
    ccall(:jl_array_sizehint, Cvoid, (Any, UInt), a, sz)
651,426✔
1340
    a
634,123✔
1341
end
1342

1343
"""
1344
    pop!(collection) -> item
1345

1346
Remove an item in `collection` and return it. If `collection` is an
1347
ordered container, the last item is returned; for unordered containers,
1348
an arbitrary element is returned.
1349

1350
See also: [`popfirst!`](@ref), [`popat!`](@ref), [`delete!`](@ref), [`deleteat!`](@ref), [`splice!`](@ref), and [`push!`](@ref).
1351

1352
# Examples
1353
```jldoctest
1354
julia> A=[1, 2, 3]
1355
3-element Vector{Int64}:
1356
 1
1357
 2
1358
 3
1359

1360
julia> pop!(A)
1361
3
1362

1363
julia> A
1364
2-element Vector{Int64}:
1365
 1
1366
 2
1367

1368
julia> S = Set([1, 2])
1369
Set{Int64} with 2 elements:
1370
  2
1371
  1
1372

1373
julia> pop!(S)
1374
2
1375

1376
julia> S
1377
Set{Int64} with 1 element:
1378
  1
1379

1380
julia> pop!(Dict(1=>2))
1381
1 => 2
1382
```
1383
"""
1384
function pop!(a::Vector)
61,446✔
1385
    if isempty(a)
295,097,615✔
1386
        _throw_argerror("array must be non-empty")
1✔
1387
    end
1388
    item = a[end]
295,097,614✔
1389
    _deleteend!(a, 1)
295,097,614✔
1390
    return item
295,097,614✔
1391
end
1392

1393
"""
1394
    popat!(a::Vector, i::Integer, [default])
1395

1396
Remove the item at the given `i` and return it. Subsequent items
1397
are shifted to fill the resulting gap.
1398
When `i` is not a valid index for `a`, return `default`, or throw an error if
1399
`default` is not specified.
1400

1401
See also: [`pop!`](@ref), [`popfirst!`](@ref), [`deleteat!`](@ref), [`splice!`](@ref).
1402

1403
!!! compat "Julia 1.5"
1404
    This function is available as of Julia 1.5.
1405

1406
# Examples
1407
```jldoctest
1408
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1409
3
1410

1411
julia> a
1412
3-element Vector{Int64}:
1413
 4
1414
 2
1415
 1
1416

1417
julia> popat!(a, 4, missing)
1418
missing
1419

1420
julia> popat!(a, 4)
1421
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1422
[...]
1423
```
1424
"""
1425
function popat!(a::Vector, i::Integer)
5✔
1426
    x = a[i]
5✔
1427
    _deleteat!(a, i, 1)
2✔
1428
    x
2✔
1429
end
1430

1431
function popat!(a::Vector, i::Integer, default)
2✔
1432
    if 1 <= i <= length(a)
2✔
1433
        x = @inbounds a[i]
1✔
1434
        _deleteat!(a, i, 1)
1✔
1435
        x
1✔
1436
    else
1437
        default
1✔
1438
    end
1439
end
1440

1441
"""
1442
    pushfirst!(collection, items...) -> collection
1443

1444
Insert one or more `items` at the beginning of `collection`.
1445

1446
This function is called `unshift` in many other programming languages.
1447

1448
# Examples
1449
```jldoctest
1450
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1451
6-element Vector{Int64}:
1452
 5
1453
 6
1454
 1
1455
 2
1456
 3
1457
 4
1458
```
1459
"""
1460
function pushfirst!(a::Vector{T}, item) where T
58,402✔
1461
    item = item isa T ? item : convert(T, item)::T
58,386✔
1462
    _growbeg!(a, 1)
91,870✔
1463
    @_safeindex a[1] = item
91,870✔
1464
    return a
58,402✔
1465
end
1466

1467
# specialize and optimize the single argument case
1468
function pushfirst!(a::Vector{Any}, @nospecialize x)
109✔
1469
    _growbeg!(a, 1)
727,136✔
1470
    @_safeindex a[1] = x
727,136✔
1471
    return a
109✔
1472
end
1473
function pushfirst!(a::Vector{Any}, @nospecialize x...)
755✔
1474
    @_terminates_locally_meta
2✔
1475
    na = length(a)
2✔
1476
    nx = length(x)
2✔
1477
    _growbeg!(a, nx)
755✔
1478
    @_safeindex for i = 1:nx
755✔
1479
        a[i] = x[i]
1,512✔
1480
    end
2,269✔
1481
    return a
755✔
1482
end
1483

1484
"""
1485
    popfirst!(collection) -> item
1486

1487
Remove the first `item` from `collection`.
1488

1489
This function is called `shift` in many other programming languages.
1490

1491
See also: [`pop!`](@ref), [`popat!`](@ref), [`delete!`](@ref).
1492

1493
# Examples
1494
```jldoctest
1495
julia> A = [1, 2, 3, 4, 5, 6]
1496
6-element Vector{Int64}:
1497
 1
1498
 2
1499
 3
1500
 4
1501
 5
1502
 6
1503

1504
julia> popfirst!(A)
1505
1
1506

1507
julia> A
1508
5-element Vector{Int64}:
1509
 2
1510
 3
1511
 4
1512
 5
1513
 6
1514
```
1515
"""
1516
function popfirst!(a::Vector)
1,036,380✔
1517
    if isempty(a)
19,164,773✔
1518
        _throw_argerror("array must be non-empty")
1✔
1519
    end
1520
    item = a[1]
19,164,772✔
1521
    _deletebeg!(a, 1)
19,164,772✔
1522
    return item
19,164,772✔
1523
end
1524

1525
"""
1526
    insert!(a::Vector, index::Integer, item)
1527

1528
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1529
the resulting `a`.
1530

1531
See also: [`push!`](@ref), [`replace`](@ref), [`popat!`](@ref), [`splice!`](@ref).
1532

1533
# Examples
1534
```jldoctest
1535
julia> insert!(Any[1:6;], 3, "here")
1536
7-element Vector{Any}:
1537
 1
1538
 2
1539
  "here"
1540
 3
1541
 4
1542
 5
1543
 6
1544
```
1545
"""
1546
function insert!(a::Array{T,1}, i::Integer, item) where T
309,234✔
1547
    # Throw convert error before changing the shape of the array
1548
    _item = item isa T ? item : convert(T, item)::T
309,222✔
1549
    _growat!(a, i, 1)
66,310,687✔
1550
    # _growat! already did bound check
1551
    @inbounds a[i] = _item
66,310,681✔
1552
    return a
309,228✔
1553
end
1554

1555
"""
1556
    deleteat!(a::Vector, i::Integer)
1557

1558
Remove the item at the given `i` and return the modified `a`. Subsequent items
1559
are shifted to fill the resulting gap.
1560

1561
See also: [`keepat!`](@ref), [`delete!`](@ref), [`popat!`](@ref), [`splice!`](@ref).
1562

1563
# Examples
1564
```jldoctest
1565
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1566
5-element Vector{Int64}:
1567
 6
1568
 4
1569
 3
1570
 2
1571
 1
1572
```
1573
"""
1574
function deleteat!(a::Vector, i::Integer)
30✔
1575
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
30✔
1576
    _deleteat!(a, i, 1)
212,024✔
1577
    return a
24✔
1578
end
1579

1580
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
4,556✔
1581
    if eltype(r) === Bool
4,556✔
1582
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
×
1583
    else
1584
        n = length(a)
4,556✔
1585
        f = first(r)
4,556✔
1586
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
4,556✔
1587
        isempty(r) || _deleteat!(a, f, length(r))
18,945✔
1588
        return a
11,227✔
1589
    end
1590
end
1591

1592
"""
1593
    deleteat!(a::Vector, inds)
1594

1595
Remove the items at the indices given by `inds`, and return the modified `a`.
1596
Subsequent items are shifted to fill the resulting gap.
1597

1598
`inds` can be either an iterator or a collection of sorted and unique integer indices,
1599
or a boolean vector of the same length as `a` with `true` indicating entries to delete.
1600

1601
# Examples
1602
```jldoctest
1603
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1604
3-element Vector{Int64}:
1605
 5
1606
 3
1607
 1
1608

1609
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1610
3-element Vector{Int64}:
1611
 5
1612
 3
1613
 1
1614

1615
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1616
ERROR: ArgumentError: indices must be unique and sorted
1617
Stacktrace:
1618
[...]
1619
```
1620
"""
1621
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1622
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
44,508✔
1623

1624
struct Nowhere; end
1625
push!(::Nowhere, _) = nothing
47✔
1626
_growend!(::Nowhere, _) = nothing
×
1627

1628
@inline function _push_deleted!(dltd, a::Vector, ind)
49✔
1629
    if @inbounds isassigned(a, ind)
49,440✔
1630
        push!(dltd, @inbounds a[ind])
49,451✔
1631
    else
1632
        _growend!(dltd, 1)
1✔
1633
    end
1634
end
1635

1636
@inline function _copy_item!(a::Vector, p, q)
271✔
1637
    if @inbounds isassigned(a, q)
25,840✔
1638
        @inbounds a[p] = a[q]
25,859✔
1639
    else
1640
        _unsetindex!(a, p)
1✔
1641
    end
1642
end
1643

1644
function _deleteat!(a::Vector, inds, dltd=Nowhere())
44,559✔
1645
    n = length(a)
89,055✔
1646
    y = iterate(inds)
44,539✔
1647
    y === nothing && return a
44,528✔
1648
    (p, s) = y
27✔
1649
    checkbounds(a, p)
44,529✔
1650
    _push_deleted!(dltd, a, p)
44,522✔
1651
    q = p+1
44,517✔
1652
    while true
49,440✔
1653
        y = iterate(inds, s)
93,951✔
1654
        y === nothing && break
49,440✔
1655
        (i,s) = y
28✔
1656
        if !(q <= i <= n)
4,925✔
1657
            if i < q
2✔
1658
                _throw_argerror("indices must be unique and sorted")
1✔
1659
            else
1660
                throw(BoundsError())
1✔
1661
            end
1662
        end
1663
        while q < i
6,802✔
1664
            _copy_item!(a, p, q)
1,888✔
1665
            p += 1; q += 1
3,758✔
1666
        end
1,879✔
1667
        _push_deleted!(dltd, a, i)
4,931✔
1668
        q = i+1
4,923✔
1669
    end
4,923✔
1670
    while q <= n
68,286✔
1671
        _copy_item!(a, p, q)
23,783✔
1672
        p += 1; q += 1
47,542✔
1673
    end
23,771✔
1674
    _deleteend!(a, n-p+1)
44,515✔
1675
    return a
44,515✔
1676
end
1677

1678
# Simpler and more efficient version for logical indexing
1679
function deleteat!(a::Vector, inds::AbstractVector{Bool})
23✔
1680
    n = length(a)
23✔
1681
    length(inds) == n || throw(BoundsError(a, inds))
26✔
1682
    p = 1
20✔
1683
    for (q, i) in enumerate(inds)
39✔
1684
        _copy_item!(a, p, q)
190✔
1685
        p += !i
190✔
1686
    end
361✔
1687
    _deleteend!(a, n-p+1)
20✔
1688
    return a
20✔
1689
end
1690

1691
const _default_splice = []
1692

1693
"""
1694
    splice!(a::Vector, index::Integer, [replacement]) -> item
1695

1696
Remove the item at the given index, and return the removed item.
1697
Subsequent items are shifted left to fill the resulting gap.
1698
If specified, replacement values from an ordered
1699
collection will be spliced in place of the removed item.
1700

1701
See also: [`replace`](@ref), [`delete!`](@ref), [`deleteat!`](@ref), [`pop!`](@ref), [`popat!`](@ref).
1702

1703
# Examples
1704
```jldoctest
1705
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1706
2
1707

1708
julia> A
1709
5-element Vector{Int64}:
1710
 6
1711
 5
1712
 4
1713
 3
1714
 1
1715

1716
julia> splice!(A, 5, -1)
1717
1
1718

1719
julia> A
1720
5-element Vector{Int64}:
1721
  6
1722
  5
1723
  4
1724
  3
1725
 -1
1726

1727
julia> splice!(A, 1, [-1, -2, -3])
1728
6
1729

1730
julia> A
1731
7-element Vector{Int64}:
1732
 -1
1733
 -2
1734
 -3
1735
  5
1736
  4
1737
  3
1738
 -1
1739
```
1740

1741
To insert `replacement` before an index `n` without removing any items, use
1742
`splice!(collection, n:n-1, replacement)`.
1743
"""
1744
function splice!(a::Vector, i::Integer, ins=_default_splice)
32✔
1745
    v = a[i]
32✔
1746
    m = length(ins)
26✔
1747
    if m == 0
26✔
1748
        _deleteat!(a, i, 1)
11✔
1749
    elseif m == 1
15✔
1750
        a[i] = ins[1]
5✔
1751
    else
1752
        _growat!(a, i, m-1)
10✔
1753
        k = 1
10✔
1754
        for x in ins
10✔
1755
            a[i+k-1] = x
35✔
1756
            k += 1
35✔
1757
        end
35✔
1758
    end
1759
    return v
26✔
1760
end
1761

1762
"""
1763
    splice!(a::Vector, indices, [replacement]) -> items
1764

1765
Remove items at specified indices, and return a collection containing
1766
the removed items.
1767
Subsequent items are shifted left to fill the resulting gaps.
1768
If specified, replacement values from an ordered collection will be spliced in
1769
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
1770

1771
To insert `replacement` before an index `n` without removing any items, use
1772
`splice!(collection, n:n-1, replacement)`.
1773

1774
!!! compat "Julia 1.5"
1775
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1776

1777
!!! compat "Julia 1.8"
1778
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1779

1780
# Examples
1781
```jldoctest
1782
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
1783
Int64[]
1784

1785
julia> A
1786
8-element Vector{Int64}:
1787
 -1
1788
 -2
1789
 -3
1790
  2
1791
  5
1792
  4
1793
  3
1794
 -1
1795
```
1796
"""
1797
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
72✔
1798
    v = a[r]
80✔
1799
    m = length(ins)
64✔
1800
    if m == 0
64✔
1801
        deleteat!(a, r)
40✔
1802
        return v
22✔
1803
    end
1804

1805
    n = length(a)
42✔
1806
    f = first(r)
42✔
1807
    l = last(r)
42✔
1808
    d = length(r)
42✔
1809

1810
    if m < d
42✔
1811
        delta = d - m
9✔
1812
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
15✔
1813
    elseif m > d
33✔
1814
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
26✔
1815
    end
1816

1817
    k = 1
42✔
1818
    for x in ins
42✔
1819
        a[f+k-1] = x
112✔
1820
        k += 1
112✔
1821
    end
154✔
1822
    return v
42✔
1823
end
1824

1825
splice!(a::Vector, inds) = (dltds = eltype(a)[]; _deleteat!(a, inds, dltds); dltds)
3✔
1826

1827
function empty!(a::Vector)
79,980✔
1828
    _deleteend!(a, length(a))
62,345,532✔
1829
    return a
62,345,532✔
1830
end
1831

1832
_memcmp(a, b, len) = ccall(:memcmp, Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), a, b, len % Csize_t) % Int
65,281✔
1833

1834
# use memcmp for cmp on byte arrays
1835
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
1836
    c = _memcmp(a, b, min(length(a),length(b)))
3✔
1837
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
1838
end
1839

1840
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
1841
# use memcmp for == on bit integer types
1842
==(a::Arr, b::Arr) where {Arr <: BitIntegerArray} =
1,522✔
1843
    size(a) == size(b) && 0 == _memcmp(a, b, sizeof(eltype(Arr)) * length(a))
1844

1845
# this is ~20% faster than the generic implementation above for very small arrays
1846
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
5,434✔
1847
    len = length(a)
40,011✔
1848
    len == length(b) && 0 == _memcmp(a, b, sizeof(eltype(Arr)) * len)
40,013✔
1849
end
1850

1851
"""
1852
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
1853

1854
Return a copy of `v` reversed from start to stop.  See also [`Iterators.reverse`](@ref)
1855
for reverse-order iteration without making a copy, and in-place [`reverse!`](@ref).
1856

1857
# Examples
1858
```jldoctest
1859
julia> A = Vector(1:5)
1860
5-element Vector{Int64}:
1861
 1
1862
 2
1863
 3
1864
 4
1865
 5
1866

1867
julia> reverse(A)
1868
5-element Vector{Int64}:
1869
 5
1870
 4
1871
 3
1872
 2
1873
 1
1874

1875
julia> reverse(A, 1, 4)
1876
5-element Vector{Int64}:
1877
 4
1878
 3
1879
 2
1880
 1
1881
 5
1882

1883
julia> reverse(A, 3, 5)
1884
5-element Vector{Int64}:
1885
 1
1886
 2
1887
 5
1888
 4
1889
 3
1890
```
1891
"""
1892
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
1,342✔
1893
    s, n = Int(start), Int(stop)
64✔
1894
    B = similar(A)
1,343✔
1895
    for i = firstindex(A):s-1
1,346✔
1896
        B[i] = A[i]
14✔
1897
    end
24✔
1898
    for i = s:n
2,678✔
1899
        B[i] = A[n+s-i]
105,202✔
1900
    end
209,064✔
1901
    for i = n+1:lastindex(A)
1,346✔
1902
        B[i] = A[i]
20✔
1903
    end
36✔
1904
    return B
1,342✔
1905
end
1906

1907
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
1908
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
1909
    @eval begin
1910
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
87,761,213✔
1911
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
3,220✔
1912
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
1913
        function $_f(A::AbstractVector, dim::Integer)
7✔
1914
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
1915
            return $_f(A, :)
3✔
1916
        end
1917
    end
1918
end
1919

1920
function reverseind(a::AbstractVector, i::Integer)
3✔
1921
    li = LinearIndices(a)
3✔
1922
    first(li) + last(li) - i
3✔
1923
end
1924

1925
# This implementation of `midpoint` is performance-optimized but safe
1926
# only if `lo <= hi`.
1927
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
2,360,194✔
1928
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
1929

1930
"""
1931
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
1932

1933
In-place version of [`reverse`](@ref).
1934

1935
# Examples
1936
```jldoctest
1937
julia> A = Vector(1:5)
1938
5-element Vector{Int64}:
1939
 1
1940
 2
1941
 3
1942
 4
1943
 5
1944

1945
julia> reverse!(A);
1946

1947
julia> A
1948
5-element Vector{Int64}:
1949
 5
1950
 4
1951
 3
1952
 2
1953
 1
1954
```
1955
"""
1956
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
56,320✔
1957
    s, n = Int(start), Int(stop)
8,225✔
1958
    if n > s # non-empty and non-trivial
56,317✔
1959
        liv = LinearIndices(v)
53,123✔
1960
        if !(first(liv) ≤ s ≤ last(liv))
53,123✔
1961
            throw(BoundsError(v, s))
3✔
1962
        elseif !(first(liv) ≤ n ≤ last(liv))
53,120✔
1963
            throw(BoundsError(v, n))
1✔
1964
        end
1965
        r = n
7,527✔
1966
        @inbounds for i in s:midpoint(s, n-1)
106,238✔
1967
            v[i], v[r] = v[r], v[i]
1,539,331✔
1968
            r -= 1
1,535,075✔
1969
        end
3,017,031✔
1970
    end
1971
    return v
56,313✔
1972
end
1973

1974
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
1975

1976
vcat() = Vector{Any}()
212✔
1977
hcat() = Vector{Any}()
1✔
1978

1979
function hcat(V::Vector{T}...) where T
560✔
1980
    height = length(V[1])
560✔
1981
    for j = 2:length(V)
561✔
1982
        if length(V[j]) != height
626✔
1983
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
1984
        end
1985
    end
723✔
1986
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
559✔
1987
end
1988
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
1989

1990
function vcat(arrays::Vector{T}...) where T
7,014✔
1991
    n = 0
6,753✔
1992
    for a in arrays
7,014✔
1993
        n += length(a)
2,014,185✔
1994
    end
2,021,184✔
1995
    arr = Vector{T}(undef, n)
7,014✔
1996
    nd = 1
6,753✔
1997
    for a in arrays
7,014✔
1998
        na = length(a)
2,014,185✔
1999
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,014,185✔
2000
        unsafe_copyto!(arr, nd, a, 1, na)
2,014,185✔
2001
        nd += na
2,014,185✔
2002
    end
2,021,184✔
2003
    return arr
7,014✔
2004
end
2005
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
70✔
2006

2007
# disambiguation with LinAlg/special.jl
2008
# Union{Number,Vector,Matrix} is for LinearAlgebra._DenseConcatGroup
2009
# VecOrMat{T} is for LinearAlgebra._TypedDenseConcatGroup
2010
hcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(2))
104✔
2011
hcat(A::VecOrMat{T}...) where {T} = typed_hcat(T, A...)
175✔
2012
vcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(1))
116✔
2013
vcat(A::VecOrMat{T}...) where {T} = typed_vcat(T, A...)
541✔
2014
hvcat(rows::Tuple{Vararg{Int}}, xs::Union{Number,Vector,Matrix}...) =
91✔
2015
    typed_hvcat(promote_eltypeof(xs...), rows, xs...)
2016
hvcat(rows::Tuple{Vararg{Int}}, xs::VecOrMat{T}...) where {T} =
63✔
2017
    typed_hvcat(T, rows, xs...)
2018

2019
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))
1✔
2020

2021
## find ##
2022

2023
"""
2024
    findnext(A, i)
2025

2026
Find the next index after or including `i` of a `true` element of `A`,
2027
or `nothing` if not found.
2028

2029
Indices are of the same type as those returned by [`keys(A)`](@ref)
2030
and [`pairs(A)`](@ref).
2031

2032
# Examples
2033
```jldoctest
2034
julia> A = [false, false, true, false]
2035
4-element Vector{Bool}:
2036
 0
2037
 0
2038
 1
2039
 0
2040

2041
julia> findnext(A, 1)
2042
3
2043

2044
julia> findnext(A, 4) # returns nothing, but not printed in the REPL
2045

2046
julia> A = [false false; true false]
2047
2×2 Matrix{Bool}:
2048
 0  0
2049
 1  0
2050

2051
julia> findnext(A, CartesianIndex(1, 1))
2052
CartesianIndex(2, 1)
2053
```
2054
"""
2055
findnext(A, start) = findnext(identity, A, start)
328✔
2056

2057
"""
2058
    findfirst(A)
2059

2060
Return the index or key of the first `true` value in `A`.
2061
Return `nothing` if no such value is found.
2062
To search for other kinds of values, pass a predicate as the first argument.
2063

2064
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2065
and [`pairs(A)`](@ref).
2066

2067
See also: [`findall`](@ref), [`findnext`](@ref), [`findlast`](@ref), [`searchsortedfirst`](@ref).
2068

2069
# Examples
2070
```jldoctest
2071
julia> A = [false, false, true, false]
2072
4-element Vector{Bool}:
2073
 0
2074
 0
2075
 1
2076
 0
2077

2078
julia> findfirst(A)
2079
3
2080

2081
julia> findfirst(falses(3)) # returns nothing, but not printed in the REPL
2082

2083
julia> A = [false false; true false]
2084
2×2 Matrix{Bool}:
2085
 0  0
2086
 1  0
2087

2088
julia> findfirst(A)
2089
CartesianIndex(2, 1)
2090
```
2091
"""
2092
findfirst(A) = findfirst(identity, A)
2✔
2093

2094
# Needed for bootstrap, and allows defining only an optimized findnext method
2095
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
225✔
2096

2097
"""
2098
    findnext(predicate::Function, A, i)
2099

2100
Find the next index after or including `i` of an element of `A`
2101
for which `predicate` returns `true`, or `nothing` if not found.
2102

2103
Indices are of the same type as those returned by [`keys(A)`](@ref)
2104
and [`pairs(A)`](@ref).
2105

2106
# Examples
2107
```jldoctest
2108
julia> A = [1, 4, 2, 2];
2109

2110
julia> findnext(isodd, A, 1)
2111
1
2112

2113
julia> findnext(isodd, A, 2) # returns nothing, but not printed in the REPL
2114

2115
julia> A = [1 4; 2 2];
2116

2117
julia> findnext(isodd, A, CartesianIndex(1, 1))
2118
CartesianIndex(1, 1)
2119
```
2120
"""
2121
function findnext(testf::Function, A, start)
19,842✔
2122
    i = oftype(first(keys(A)), start)
17,893✔
2123
    l = last(keys(A))
41,362,645✔
2124
    i > l && return nothing
41,362,645✔
2125
    while true
171,439,057✔
2126
        testf(A[i]) && return i
171,443,080✔
2127
        i == l && break
171,049,381✔
2128
        # nextind(A, l) can throw/overflow
2129
        i = nextind(A, i)
167,034,799✔
2130
    end
167,034,780✔
2131
    return nothing
4,014,577✔
2132
end
2133

2134
"""
2135
    findfirst(predicate::Function, A)
2136

2137
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2138
Return `nothing` if there is no such element.
2139

2140
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2141
and [`pairs(A)`](@ref).
2142

2143
# Examples
2144
```jldoctest
2145
julia> A = [1, 4, 2, 2]
2146
4-element Vector{Int64}:
2147
 1
2148
 4
2149
 2
2150
 2
2151

2152
julia> findfirst(iseven, A)
2153
2
2154

2155
julia> findfirst(x -> x>10, A) # returns nothing, but not printed in the REPL
2156

2157
julia> findfirst(isequal(4), A)
2158
2
2159

2160
julia> A = [1 4; 2 2]
2161
2×2 Matrix{Int64}:
2162
 1  4
2163
 2  2
2164

2165
julia> findfirst(iseven, A)
2166
CartesianIndex(2, 1)
2167
```
2168
"""
2169
function findfirst(testf::Function, A)
14✔
2170
    for (i, a) in pairs(A)
22✔
2171
        testf(a) && return i
14✔
2172
    end
11✔
2173
    return nothing
7✔
2174
end
2175

2176
# Needed for bootstrap, and allows defining only an optimized findnext method
2177
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
213,125,413✔
2178
    findnext(testf, A, first(keys(A)))
2179

2180
findfirst(p::Union{Fix2{typeof(isequal),Int},Fix2{typeof(==),Int}}, r::OneTo{Int}) =
3✔
2181
    1 <= p.x <= r.stop ? p.x : nothing
2182

2183
findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::AbstractUnitRange) where {T<:Integer} =
4✔
2184
    first(r) <= p.x <= last(r) ? firstindex(r) + Int(p.x - first(r)) : nothing
2185

2186
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2187
    isempty(r) && return nothing
6✔
2188
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2189
    d = convert(S, p.x - first(r))::S
3✔
2190
    iszero(d % step(r)) || return nothing
3✔
2191
    return d ÷ step(r) + 1
3✔
2192
end
2193

2194
"""
2195
    findprev(A, i)
2196

2197
Find the previous index before or including `i` of a `true` element of `A`,
2198
or `nothing` if not found.
2199

2200
Indices are of the same type as those returned by [`keys(A)`](@ref)
2201
and [`pairs(A)`](@ref).
2202

2203
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2204

2205
# Examples
2206
```jldoctest
2207
julia> A = [false, false, true, true]
2208
4-element Vector{Bool}:
2209
 0
2210
 0
2211
 1
2212
 1
2213

2214
julia> findprev(A, 3)
2215
3
2216

2217
julia> findprev(A, 1) # returns nothing, but not printed in the REPL
2218

2219
julia> A = [false false; true true]
2220
2×2 Matrix{Bool}:
2221
 0  0
2222
 1  1
2223

2224
julia> findprev(A, CartesianIndex(2, 1))
2225
CartesianIndex(2, 1)
2226
```
2227
"""
2228
findprev(A, start) = findprev(identity, A, start)
3,769✔
2229

2230
"""
2231
    findlast(A)
2232

2233
Return the index or key of the last `true` value in `A`.
2234
Return `nothing` if there is no `true` value in `A`.
2235

2236
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2237
and [`pairs(A)`](@ref).
2238

2239
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2240

2241
# Examples
2242
```jldoctest
2243
julia> A = [true, false, true, false]
2244
4-element Vector{Bool}:
2245
 1
2246
 0
2247
 1
2248
 0
2249

2250
julia> findlast(A)
2251
3
2252

2253
julia> A = falses(2,2);
2254

2255
julia> findlast(A) # returns nothing, but not printed in the REPL
2256

2257
julia> A = [true false; true false]
2258
2×2 Matrix{Bool}:
2259
 1  0
2260
 1  0
2261

2262
julia> findlast(A)
2263
CartesianIndex(2, 1)
2264
```
2265
"""
2266
findlast(A) = findlast(identity, A)
23✔
2267

2268
# Needed for bootstrap, and allows defining only an optimized findprev method
2269
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
3,890✔
2270

2271
"""
2272
    findprev(predicate::Function, A, i)
2273

2274
Find the previous index before or including `i` of an element of `A`
2275
for which `predicate` returns `true`, or `nothing` if not found.
2276

2277
Indices are of the same type as those returned by [`keys(A)`](@ref)
2278
and [`pairs(A)`](@ref).
2279

2280
# Examples
2281
```jldoctest
2282
julia> A = [4, 6, 1, 2]
2283
4-element Vector{Int64}:
2284
 4
2285
 6
2286
 1
2287
 2
2288

2289
julia> findprev(isodd, A, 1) # returns nothing, but not printed in the REPL
2290

2291
julia> findprev(isodd, A, 3)
2292
3
2293

2294
julia> A = [4 6; 1 2]
2295
2×2 Matrix{Int64}:
2296
 4  6
2297
 1  2
2298

2299
julia> findprev(isodd, A, CartesianIndex(1, 2))
2300
CartesianIndex(2, 1)
2301
```
2302
"""
2303
function findprev(testf::Function, A, start)
28,391✔
2304
    f = first(keys(A))
28,391✔
2305
    i = oftype(f, start)
28,402✔
2306
    i < f && return nothing
29,630✔
2307
    while true
33,866✔
2308
        testf(A[i]) && return i
33,909✔
2309
        i == f && break
4,321✔
2310
        # prevind(A, f) can throw/underflow
2311
        i = prevind(A, i)
4,264✔
2312
    end
4,236✔
2313
    return nothing
54✔
2314
end
2315

2316
"""
2317
    findlast(predicate::Function, A)
2318

2319
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2320
Return `nothing` if there is no such element.
2321

2322
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2323
and [`pairs(A)`](@ref).
2324

2325
# Examples
2326
```jldoctest
2327
julia> A = [1, 2, 3, 4]
2328
4-element Vector{Int64}:
2329
 1
2330
 2
2331
 3
2332
 4
2333

2334
julia> findlast(isodd, A)
2335
3
2336

2337
julia> findlast(x -> x > 5, A) # returns nothing, but not printed in the REPL
2338

2339
julia> A = [1 2; 3 4]
2340
2×2 Matrix{Int64}:
2341
 1  2
2342
 3  4
2343

2344
julia> findlast(isodd, A)
2345
CartesianIndex(2, 1)
2346
```
2347
"""
2348
function findlast(testf::Function, A)
4✔
2349
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2350
        testf(a) && return i
6✔
2351
    end
6✔
2352
    return nothing
2✔
2353
end
2354

2355
# Needed for bootstrap, and allows defining only an optimized findprev method
2356
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
2,901✔
2357
    findprev(testf, A, last(keys(A)))
2358

2359
"""
2360
    findall(f::Function, A)
2361

2362
Return a vector `I` of the indices or keys of `A` where `f(A[I])` returns `true`.
2363
If there are no such elements of `A`, return an empty array.
2364

2365
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2366
and [`pairs(A)`](@ref).
2367

2368
# Examples
2369
```jldoctest
2370
julia> x = [1, 3, 4]
2371
3-element Vector{Int64}:
2372
 1
2373
 3
2374
 4
2375

2376
julia> findall(isodd, x)
2377
2-element Vector{Int64}:
2378
 1
2379
 2
2380

2381
julia> A = [1 2 0; 3 4 0]
2382
2×3 Matrix{Int64}:
2383
 1  2  0
2384
 3  4  0
2385
julia> findall(isodd, A)
2386
2-element Vector{CartesianIndex{2}}:
2387
 CartesianIndex(1, 1)
2388
 CartesianIndex(2, 1)
2389

2390
julia> findall(!iszero, A)
2391
4-element Vector{CartesianIndex{2}}:
2392
 CartesianIndex(1, 1)
2393
 CartesianIndex(2, 1)
2394
 CartesianIndex(1, 2)
2395
 CartesianIndex(2, 2)
2396

2397
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2398
Dict{Symbol, Int64} with 3 entries:
2399
  :A => 10
2400
  :B => -1
2401
  :C => 0
2402

2403
julia> findall(x -> x >= 0, d)
2404
2-element Vector{Symbol}:
2405
 :A
2406
 :C
2407

2408
```
2409
"""
2410
function findall(testf::Function, A)
55✔
2411
    T = eltype(keys(A))
55✔
2412
    gen = (first(p) for p in pairs(A) if testf(last(p)))
55✔
2413
    isconcretetype(T) ? collect(T, gen) : collect(gen)
55✔
2414
end
2415

2416
# Broadcasting is much faster for small testf, and computing
2417
# integer indices from logical index using findall has a negligible cost
2418
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
277✔
2419

2420
"""
2421
    findall(A)
2422

2423
Return a vector `I` of the `true` indices or keys of `A`.
2424
If there are no such elements of `A`, return an empty array.
2425
To search for other kinds of values, pass a predicate as the first argument.
2426

2427
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2428
and [`pairs(A)`](@ref).
2429

2430
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2431

2432
# Examples
2433
```jldoctest
2434
julia> A = [true, false, false, true]
2435
4-element Vector{Bool}:
2436
 1
2437
 0
2438
 0
2439
 1
2440

2441
julia> findall(A)
2442
2-element Vector{Int64}:
2443
 1
2444
 4
2445

2446
julia> A = [true false; false true]
2447
2×2 Matrix{Bool}:
2448
 1  0
2449
 0  1
2450

2451
julia> findall(A)
2452
2-element Vector{CartesianIndex{2}}:
2453
 CartesianIndex(1, 1)
2454
 CartesianIndex(2, 2)
2455

2456
julia> findall(falses(3))
2457
Int64[]
2458
```
2459
"""
2460
function findall(A)
3✔
2461
    collect(first(p) for p in pairs(A) if last(p))
3✔
2462
end
2463

2464
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2465
function _findall(f::Function, A::AbstractArray{Bool})
18✔
2466
    n = count(f, A)
22✔
2467
    I = Vector{eltype(keys(A))}(undef, n)
18✔
2468
    isempty(I) && return I
18✔
2469
    _findall(f, I, A)
16✔
2470
end
2471

2472
function _findall(f::Function, I::Vector, A::AbstractArray{Bool})
5✔
2473
    cnt = 1
5✔
2474
    len = length(I)
5✔
2475
    for (k, v) in pairs(A)
10✔
2476
        @inbounds I[cnt] = k
57✔
2477
        cnt += f(v)
57✔
2478
        cnt > len && return I
57✔
2479
    end
104✔
2480
    # In case of impure f, this line could potentially be hit. In that case,
2481
    # we can't assume I is the correct length.
2482
    resize!(I, cnt - 1)
×
2483
end
2484

2485
function _findall(f::Function, I::Vector, A::AbstractVector{Bool})
11✔
2486
    i = firstindex(A)
11✔
2487
    cnt = 1
11✔
2488
    len = length(I)
11✔
2489
    while cnt ≤ len
374✔
2490
        @inbounds I[cnt] = i
363✔
2491
        cnt += f(@inbounds A[i])
363✔
2492
        i = nextind(A, i)
363✔
2493
    end
363✔
2494
    cnt - 1 == len ? I : resize!(I, cnt - 1)
11✔
2495
end
2496

2497
findall(f::Function, A::AbstractArray{Bool}) = _findall(f, A)
4✔
2498
findall(f::Fix2{typeof(in)}, A::AbstractArray{Bool}) = _findall(f, A)
×
2499
findall(A::AbstractArray{Bool}) = _findall(identity, A)
17✔
2500

2501
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2502
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2503
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2504

2505
# similar to Matlab's ismember
2506
"""
2507
    indexin(a, b)
2508

2509
Return an array containing the first index in `b` for
2510
each value in `a` that is a member of `b`. The output
2511
array contains `nothing` wherever `a` is not a member of `b`.
2512

2513
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2514

2515
# Examples
2516
```jldoctest
2517
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2518

2519
julia> b = ['a', 'b', 'c'];
2520

2521
julia> indexin(a, b)
2522
6-element Vector{Union{Nothing, Int64}}:
2523
 1
2524
 2
2525
 3
2526
 2
2527
  nothing
2528
 1
2529

2530
julia> indexin(b, a)
2531
3-element Vector{Union{Nothing, Int64}}:
2532
 1
2533
 2
2534
 3
2535
```
2536
"""
2537
function indexin(a, b::AbstractArray)
7✔
2538
    inds = keys(b)
7✔
2539
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2540
    for (val, ind) in zip(b, inds)
14✔
2541
        get!(bdict, val, ind)
30✔
2542
    end
53✔
2543
    return Union{eltype(inds), Nothing}[
7✔
2544
        get(bdict, i, nothing) for i in a
2545
    ]
2546
end
2547

2548
function _findin(a::Union{AbstractArray, Tuple}, b)
13✔
2549
    ind  = Vector{eltype(keys(a))}()
13✔
2550
    bset = Set(b)
13✔
2551
    @inbounds for (i,ai) in pairs(a)
25✔
2552
        ai in bset && push!(ind, i)
53✔
2553
    end
94✔
2554
    ind
13✔
2555
end
2556

2557
# If two collections are already sorted, _findin can be computed with
2558
# a single traversal of the two collections. This is much faster than
2559
# using a hash table (although it has the same complexity).
2560
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
9✔
2561
    viter, witer = keys(v), eachindex(w)
9✔
2562
    out  = eltype(viter)[]
9✔
2563
    vy, wy = iterate(viter), iterate(witer)
17✔
2564
    if vy === nothing || wy === nothing
17✔
2565
        return out
2✔
2566
    end
2567
    viteri, i = vy
7✔
2568
    witerj, j = wy
7✔
2569
    @inbounds begin
7✔
2570
        vi, wj = v[viteri], w[witerj]
7✔
2571
        while true
54✔
2572
            if isless(vi, wj)
56✔
2573
                vy = iterate(viter, i)
25✔
2574
                if vy === nothing
14✔
2575
                    break
2✔
2576
                end
2577
                viteri, i = vy
12✔
2578
                vi        = v[viteri]
12✔
2579
            elseif isless(wj, vi)
40✔
2580
                wy = iterate(witer, j)
44✔
2581
                if wy === nothing
24✔
2582
                    break
4✔
2583
                end
2584
                witerj, j = wy
20✔
2585
                wj        = w[witerj]
20✔
2586
            else
2587
                push!(out, viteri)
16✔
2588
                vy = iterate(viter, i)
25✔
2589
                if vy === nothing
16✔
2590
                    break
1✔
2591
                end
2592
                # We only increment the v iterator because v can have
2593
                # repeated matches to a single value in w
2594
                viteri, i = vy
15✔
2595
                vi        = v[viteri]
15✔
2596
            end
2597
        end
47✔
2598
    end
2599
    return out
7✔
2600
end
2601

2602
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2603
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2604
        return _sortedfindin(x, pred.x)
9✔
2605
    else
2606
        return _findin(x, pred.x)
6✔
2607
    end
2608
end
2609
# issorted fails for some element types so the method above has to be restricted
2610
# to element with isless/< defined.
2611
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
11✔
2612
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2613

2614
# Copying subregions
2615
function indcopy(sz::Dims, I::Vector)
1✔
2616
    n = length(I)
1✔
2617
    s = sz[n]
1✔
2618
    for i = n+1:length(sz)
1✔
2619
        s *= sz[i]
×
2620
    end
×
2621
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2622
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2623
    dst, src
1✔
2624
end
2625

2626
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2627
    n = length(I)
1✔
2628
    s = sz[n]
1✔
2629
    for i = n+1:length(sz)
1✔
2630
        s *= sz[i]
×
2631
    end
×
2632
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2633
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2634
    dst, src
1✔
2635
end
2636

2637
## Filter ##
2638

2639
"""
2640
    filter(f, a)
2641

2642
Return a copy of collection `a`, removing elements for which `f` is `false`.
2643
The function `f` is passed one argument.
2644

2645
!!! compat "Julia 1.4"
2646
    Support for `a` as a tuple requires at least Julia 1.4.
2647

2648
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2649

2650
# Examples
2651
```jldoctest
2652
julia> a = 1:10
2653
1:10
2654

2655
julia> filter(isodd, a)
2656
5-element Vector{Int64}:
2657
 1
2658
 3
2659
 5
2660
 7
2661
 9
2662
```
2663
"""
2664
function filter(f, a::Array{T, N}) where {T, N}
455,597✔
2665
    j = 1
442,849✔
2666
    b = Vector{T}(undef, length(a))
455,597✔
2667
    for ai in a
455,601✔
2668
        @inbounds b[j] = ai
2,523,372✔
2669
        j = ifelse(f(ai)::Bool, j+1, j)
2,528,010✔
2670
    end
2,978,905✔
2671
    resize!(b, j-1)
911,194✔
2672
    sizehint!(b, length(b))
455,597✔
2673
    b
455,597✔
2674
end
2675

2676
function filter(f, a::AbstractArray)
375✔
2677
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
375✔
2678

2679
    j = 1
375✔
2680
    idxs = Vector{Int}(undef, length(a))
378✔
2681
    for idx in eachindex(a)
621✔
2682
        @inbounds idxs[j] = idx
102,079✔
2683
        ai = @inbounds a[idx]
102,079✔
2684
        j = ifelse(f(ai)::Bool, j+1, j)
136,147✔
2685
    end
203,911✔
2686
    resize!(idxs, j-1)
748✔
2687
    res = a[idxs]
374✔
2688
    empty!(idxs)
374✔
2689
    sizehint!(idxs, 0)
374✔
2690
    return res
374✔
2691
end
2692

2693
"""
2694
    filter!(f, a)
2695

2696
Update collection `a`, removing elements for which `f` is `false`.
2697
The function `f` is passed one argument.
2698

2699
# Examples
2700
```jldoctest
2701
julia> filter!(isodd, Vector(1:10))
2702
5-element Vector{Int64}:
2703
 1
2704
 3
2705
 5
2706
 7
2707
 9
2708
```
2709
"""
2710
function filter!(f, a::AbstractVector)
906,701✔
2711
    j = firstindex(a)
806✔
2712
    for ai in a
931,990✔
2713
        @inbounds a[j] = ai
4,275,682✔
2714
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
7,025,956✔
2715
    end
5,157,103✔
2716
    j > lastindex(a) && return a
906,701✔
2717
    if a isa Vector
245✔
2718
        resize!(a, j-1)
326,302✔
2719
        sizehint!(a, j-1)
163,151✔
2720
    else
2721
        deleteat!(a, j:lastindex(a))
1✔
2722
    end
2723
    return a
163,152✔
2724
end
2725

2726
"""
2727
    filter(f)
2728

2729
Create a function that filters its arguments with function `f` using [`filter`](@ref), i.e.
2730
a function equivalent to `x -> filter(f, x)`.
2731

2732
The returned function is of type `Base.Fix1{typeof(filter)}`, which can be
2733
used to implement specialized methods.
2734

2735
# Examples
2736
```jldoctest
2737
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2738
(1, 2, 4, 6)
2739

2740
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2741
3-element Vector{Vector{Int64}}:
2742
 [2]
2743
 [2, 4]
2744
 [4]
2745
```
2746
!!! compat "Julia 1.9"
2747
    This method requires at least Julia 1.9.
2748
"""
2749
function filter(f)
1✔
2750
    Fix1(filter, f)
1✔
2751
end
2752

2753
"""
2754
    keepat!(a::Vector, inds)
2755
    keepat!(a::BitVector, inds)
2756

2757
Remove the items at all the indices which are not given by `inds`,
2758
and return the modified `a`.
2759
Items which are kept are shifted to fill the resulting gaps.
2760

2761
`inds` must be an iterator of sorted and unique integer indices.
2762
See also [`deleteat!`](@ref).
2763

2764
!!! compat "Julia 1.7"
2765
    This function is available as of Julia 1.7.
2766

2767
# Examples
2768
```jldoctest
2769
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
2770
3-element Vector{Int64}:
2771
 6
2772
 4
2773
 2
2774
```
2775
"""
2776
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
2777

2778
"""
2779
    keepat!(a::Vector, m::AbstractVector{Bool})
2780
    keepat!(a::BitVector, m::AbstractVector{Bool})
2781

2782
The in-place version of logical indexing `a = a[m]`. That is, `keepat!(a, m)` on
2783
vectors of equal length `a` and `m` will remove all elements from `a` for which
2784
`m` at the corresponding index is `false`.
2785

2786
# Examples
2787
```jldoctest
2788
julia> a = [:a, :b, :c];
2789

2790
julia> keepat!(a, [true, false, true])
2791
2-element Vector{Symbol}:
2792
 :a
2793
 :c
2794

2795
julia> a
2796
2-element Vector{Symbol}:
2797
 :a
2798
 :c
2799
```
2800
"""
2801
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
2802

2803
# set-like operators for vectors
2804
# These are moderately efficient, preserve order, and remove dupes.
2805

2806
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
15,902✔
2807
    # P, U force specialization
2808
    if pred(x, state)
14,865✔
2809
        update!(state, x)
7,568✔
2810
        true
7,568✔
2811
    else
2812
        false
7,297✔
2813
    end
2814
end
2815

2816
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
238✔
2817
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
1,041✔
2818

2819
function _grow!(pred!, v::AbstractVector, itrs)
263✔
2820
    filter!(pred!, v) # uniquify v
265✔
2821
    for itr in itrs
265✔
2822
        mapfilter(pred!, push!, itr, v)
517✔
2823
    end
762✔
2824
    return v
265✔
2825
end
2826

2827
union!(v::AbstractVector{T}, itrs...) where {T} =
232✔
2828
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
2829

2830
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
2831
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
2832

2833
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
6✔
2834
    seen = Set{eltype(v)}()
6✔
2835
    filter!(_grow_filter!(seen), v)
6✔
2836
    shrinker!(seen, itrs...)
7✔
2837
    filter!(in(seen), v)
6✔
2838
end
2839

2840
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
2841
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
2842

2843
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
1,009✔
2844

2845
function _shrink(shrinker!::F, itr, itrs) where F
945✔
2846
    T = promote_eltype(itr, itrs...)
867✔
2847
    keep = shrinker!(Set{T}(itr), itrs...)
1,960✔
2848
    vectorfilter(T, _shrink_filter!(keep), itr)
945✔
2849
end
2850

2851
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
469✔
2852
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
476✔
2853

2854
function intersect(v::AbstractVector, r::AbstractRange)
59✔
2855
    T = promote_eltype(v, r)
11✔
2856
    common = Iterators.filter(in(r), v)
63✔
2857
    seen = Set{T}(common)
63✔
2858
    return vectorfilter(T, _shrink_filter!(seen), common)
63✔
2859
end
2860
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
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