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

JuliaLang / julia / #37502

pending completion
#37502

push

local

web-flow
delete unnecessary `getindex` method (#49310)

xref: <https://github.com/JuliaLang/julia/pull/47154#discussion_r1161062960>

70609 of 82885 relevant lines covered (85.19%)

32589426.81 hits per line

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

83.33
/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,210✔
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,383,646✔
161
function vect(X::T...) where T
126,968✔
162
    @_terminates_locally_meta
37,247✔
163
    vec = Vector{T}(undef, length(X))
1,146,882✔
164
    @_safeindex for i = 1:length(X)
1,190,048✔
165
        vec[i] = X[i]
4,245,720✔
166
    end
6,316,984✔
167
    return vec
1,146,882✔
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...)
53,186✔
186
    T = promote_typeof(X...)
53,186✔
187
    return T[X...]
53,415✔
188
end
189

190
size(a::Array, d::Integer) = arraysize(a, d isa Int ? d : convert(Int, d))
2,919,733✔
191
size(a::Vector) = (arraysize(a,1),)
4,450,859,425✔
192
size(a::Matrix) = (arraysize(a,1), arraysize(a,2))
7,287,268✔
193
size(a::Array{<:Any,N}) where {N} = (@inline; ntuple(M -> size(a, M), Val(N))::Dims)
2,661,641✔
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,623,947✔
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)
1,441✔
214
isbitsunion(x) = false
11,866✔
215

216
function _unsetindex!(A::Array{T}, i::Int) where {T}
19,448✔
217
    @inline
1,512✔
218
    @boundscheck checkbounds(A, i)
3,056,669✔
219
    t = @_gc_preserve_begin A
3,056,570✔
220
    p = Ptr{Ptr{Cvoid}}(pointer(A, i))
3,056,200✔
221
    if !allocatedinline(T)
1,512✔
222
        Intrinsics.atomic_pointerset(p, C_NULL, :monotonic)
2,810,920✔
223
    elseif T isa DataType
245,388✔
224
        if !datatype_pointerfree(T)
2,008✔
225
            for j = 1:Core.sizeof(Ptr{Cvoid}):Core.sizeof(T)
1,956✔
226
                Intrinsics.atomic_pointerset(p + j - 1, C_NULL, :monotonic)
5,487✔
227
            end
8,936✔
228
        end
229
    end
230
    @_gc_preserve_end t
3,056,383✔
231
    return A
3,056,251✔
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
elsize(@nospecialize _::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
1,772,150✔
256
sizeof(a::Array) = Core.sizeof(a)
3,423,808✔
257

258
function isassigned(a::Array, i::Int...)
14,078,493✔
259
    @inline
8,461,115✔
260
    @boundscheck checkbounds(Bool, a, i...) || return false
2,034,217,523✔
261
    ii = (_sub2ind(size(a), i...) % UInt) - 1
1,977,246,047✔
262
    ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii) == 1
2,033,808,839✔
263
end
264

265
## copy ##
266

267
"""
268
    unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
269

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

273
The `unsafe` prefix on this function indicates that no validation is performed on the
274
pointers `dest` and `src` to ensure that they are valid. Incorrect usage may corrupt or
275
segfault your program, in the same manner as C.
276
"""
277
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
2,183,744✔
278
    # Do not use this to copy data between pointer arrays.
279
    # It can't be made safe no matter how carefully you checked.
280
    ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
18,178,819✔
281
          dest, src, n * aligned_sizeof(T))
282
    return dest
17,368,996✔
283
end
284

285

286
function _unsafe_copyto!(dest, doffs, src, soffs, n)
23,793,802✔
287
    destp = pointer(dest, doffs)
23,793,802✔
288
    srcp = pointer(src, soffs)
23,793,802✔
289
    @inbounds if destp < srcp || destp > srcp + n
38,997,719✔
290
        for i = 1:n
47,587,602✔
291
            if isassigned(src, soffs + i - 1)
134,263,162✔
292
                dest[doffs + i - 1] = src[soffs + i - 1]
137,815,481✔
293
            else
294
                _unsetindex!(dest, doffs + i - 1)
720✔
295
            end
296
        end
244,732,283✔
297
    else
298
        for i = n:-1:1
×
299
            if isassigned(src, soffs + i - 1)
×
300
                dest[doffs + i - 1] = src[soffs + i - 1]
×
301
            else
302
                _unsetindex!(dest, doffs + i - 1)
×
303
            end
304
        end
×
305
    end
306
    return dest
23,793,561✔
307
end
308

309
"""
310
    unsafe_copyto!(dest::Array, do, src::Array, so, N)
311

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

315
The `unsafe` prefix on this function indicates that no validation is performed to ensure
316
that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
317
the same manner as C.
318
"""
319
function unsafe_copyto!(dest::Array{T}, doffs, src::Array{T}, soffs, n) where T
4,065,451✔
320
    t1 = @_gc_preserve_begin dest
120,351,640✔
321
    t2 = @_gc_preserve_begin src
120,351,640✔
322
    destp = pointer(dest, doffs)
120,351,640✔
323
    srcp = pointer(src, soffs)
120,351,651✔
324
    if !allocatedinline(T)
4,062,817✔
325
        ccall(:jl_array_ptr_copy, Cvoid, (Any, Ptr{Cvoid}, Any, Ptr{Cvoid}, Int),
62,158,171✔
326
              dest, destp, src, srcp, n)
327
    elseif isbitstype(T)
2,040,906✔
328
        ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
39,454,362✔
329
              destp, srcp, n * aligned_sizeof(T))
330
    elseif isbitsunion(T)
6,199✔
331
        ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
81✔
332
              destp, srcp, n * aligned_sizeof(T))
333
        # copy selector bytes
334
        ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
81✔
335
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), dest) + doffs - 1,
336
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), src) + soffs - 1,
337
              n)
338
    else
339
        _unsafe_copyto!(dest, doffs, src, soffs, n)
18,739,037✔
340
    end
341
    @_gc_preserve_end t2
120,351,640✔
342
    @_gc_preserve_end t1
120,351,640✔
343
    return dest
41,482,306✔
344
end
345

346
unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n) =
5,054,765✔
347
    _unsafe_copyto!(dest, doffs, src, soffs, n)
348

349
"""
350
    copyto!(dest, do, src, so, N)
351

352
Copy `N` elements from collection `src` starting at the linear index `so`, to array `dest` starting at
353
the index `do`. Return `dest`.
354
"""
355
function copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
56,946✔
356
    return _copyto_impl!(dest, doffs, src, soffs, n)
10,086,789✔
357
end
358

359
# this is only needed to avoid possible ambiguities with methods added in some packages
360
function copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where T
1,149,047✔
361
    return _copyto_impl!(dest, doffs, src, soffs, n)
144,376,191✔
362
end
363

364
function _copyto_impl!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
144,432,513✔
365
    n == 0 && return dest
149,431,407✔
366
    n > 0 || _throw_argerror("Number of elements to copy must be nonnegative.")
120,677,983✔
367
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
120,678,001✔
368
    @boundscheck checkbounds(src, soffs:soffs+n-1)
120,677,964✔
369
    unsafe_copyto!(dest, doffs, src, soffs, n)
120,677,958✔
370
    return dest
120,677,717✔
371
end
372

373
# Outlining this because otherwise a catastrophic inference slowdown
374
# occurs, see discussion in #27874.
375
# It is also mitigated by using a constant string.
376
_throw_argerror(s) = (@noinline; throw(ArgumentError(s)))
4,042✔
377

378
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
10,057,646✔
379

380
# also to avoid ambiguities in packages
381
copyto!(dest::Array{T}, src::Array{T}) where {T} = copyto!(dest, 1, src, 1, length(src))
39,984,781✔
382

383
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
384
# for bootstrapping purposes.
385
function fill!(dest::Array{T}, x) where T
85,753✔
386
    xT = x isa T ? x : convert(T, x)::T
85,702✔
387
    for i in eachindex(dest)
818,792,309✔
388
        @inbounds dest[i] = xT
4,919,390,177✔
389
    end
9,662,922,255✔
390
    return dest
642,934,210✔
391
end
392

393
"""
394
    copy(x)
395

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

400
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
401
"""
402
copy
403

404
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
125,343,482✔
405

406
## Constructors ##
407

408
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
8,060✔
409
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
4,098✔
410
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
7,115✔
411
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
16,291✔
412
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
1,646,037✔
413
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
54,525,362✔
414
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
277✔
415

416
# T[x...] constructs Array{T,1}
417
"""
418
    getindex(type[, elements...])
419

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

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

431
julia> getindex(Int8, 1, 2, 3)
432
3-element Vector{Int8}:
433
 1
434
 2
435
 3
436
```
437
"""
438
function getindex(::Type{T}, vals...) where T
247,558✔
439
    @inline
99,472✔
440
    @_effect_free_terminates_locally_meta
99,472✔
441
    a = Vector{T}(undef, length(vals))
611,725,296✔
442
    if vals isa NTuple
99,620✔
443
        @_safeindex for i in 1:length(vals)
21,660,856✔
444
            a[i] = vals[i]
21,700,045✔
445
        end
146,254✔
446
    else
447
        # use afoldl to avoid type instability inside loop
448
        afoldl(1, vals...) do i, v
54,746✔
449
            @inbounds a[i] = v
111,999✔
450
            return i + 1
110,550✔
451
        end
452
    end
453
    return a
21,714,571✔
454
end
455

456
function getindex(::Type{Any}, @nospecialize vals...)
20,124,270✔
457
    @_effect_free_terminates_locally_meta
16,548✔
458
    a = Vector{Any}(undef, length(vals))
45,716,092✔
459
    @_safeindex for i = 1:length(vals)
60,444,881✔
460
        a[i] = vals[i]
86,118,223✔
461
    end
100,786,203✔
462
    return a
45,716,092✔
463
end
464
getindex(::Type{Any}) = Vector{Any}()
29,458,053✔
465

466
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
8,607✔
467
    ccall(:memset, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t), a, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
140,749,067✔
468
    return a
140,749,067✔
469
end
470

471
to_dim(d::Integer) = d
×
472
to_dim(d::OneTo) = last(d)
358✔
473

474
"""
475
    fill(value, dims::Tuple)
476
    fill(value, dims...)
477

478
Create an array of size `dims` with every location set to `value`.
479

480
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
481
with `1.0` in every location of the array.
482

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

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

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

503
julia> v[1] === v[2] === v[3]
504
true
505

506
julia> value = v[1]
507
Any[]
508

509
julia> push!(value, 867_5309)
510
1-element Vector{Any}:
511
 8675309
512

513
julia> v
514
3-element Vector{Vector{Any}}:
515
 [8675309]
516
 [8675309]
517
 [8675309]
518
```
519

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

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

530
julia> v2[1] === v2[2] === v2[3]
531
false
532

533
julia> push!(v2[1], 8675309)
534
1-element Vector{Any}:
535
 8675309
536

537
julia> v2
538
3-element Vector{Vector{Any}}:
539
 [8675309]
540
 []
541
 []
542
```
543

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

546
# Examples
547
```jldoctest
548
julia> fill(1.0, (2,3))
549
2×3 Matrix{Float64}:
550
 1.0  1.0  1.0
551
 1.0  1.0  1.0
552

553
julia> fill(42)
554
0-dimensional Array{Int64, 0}:
555
42
556

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

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

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

572
fill(v, dims::DimOrInd...) = fill(v, dims)
3,361,502,755✔
573
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
574
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
4,189,545,105✔
575
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
147✔
576

577
"""
578
    zeros([T=Float64,] dims::Tuple)
579
    zeros([T=Float64,] dims...)
580

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

584
# Examples
585
```jldoctest
586
julia> zeros(1)
587
1-element Vector{Float64}:
588
 0.0
589

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

598
"""
599
    ones([T=Float64,] dims::Tuple)
600
    ones([T=Float64,] dims...)
601

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

605
# Examples
606
```jldoctest
607
julia> ones(1,2)
608
1×2 Matrix{Float64}:
609
 1.0  1.0
610

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

619
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
620
    @eval begin
621
        $fname(dims::DimOrInd...) = $fname(dims)
20,446,707✔
622
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
339,328,566✔
623
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,483,720✔
624
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,190✔
625
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
36,783✔
626
            a = Array{T,N}(undef, dims)
221,924,067✔
627
            fill!(a, $felt(T))
764,071,907✔
628
            return a
221,924,067✔
629
        end
630
        function $fname(::Type{T}, dims::Tuple{}) where {T}
18✔
631
            a = Array{T}(undef)
18✔
632
            fill!(a, $felt(T))
18✔
633
            return a
18✔
634
        end
635
    end
636
end
637

638
function _one(unit::T, x::AbstractMatrix) where T
123✔
639
    require_one_based_indexing(x)
123✔
640
    m,n = size(x)
123✔
641
    m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
123✔
642
    # Matrix{T}(I, m, m)
643
    I = zeros(T, m, m)
1,585✔
644
    for i in 1:m
246✔
645
        I[i,i] = unit
399✔
646
    end
675✔
647
    I
123✔
648
end
649

650
one(x::AbstractMatrix{T}) where {T} = _one(one(T), x)
99✔
651
oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)
30✔
652

653
## Conversions ##
654

655
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
29,791✔
656

657
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
62✔
658

659
## Constructors ##
660

661
if nameof(@__MODULE__) === :Base  # avoid method overwrite
662
# constructors should make copies
663
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
25,577✔
664
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
25,452✔
665
end
666

667
## copying iterators to containers
668

669
"""
670
    collect(element_type, collection)
671

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

675
# Examples
676
```jldoctest
677
julia> collect(Float64, 1:2:5)
678
3-element Vector{Float64}:
679
 1.0
680
 3.0
681
 5.0
682
```
683
"""
684
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
20,817,852✔
685

686
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
9,994,688✔
687
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
688
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
10,823,162✔
689
    a = Vector{T}()
10,823,162✔
690
    for x in itr
16,649,273✔
691
        push!(a, x)
7,279,387✔
692
    end
8,732,662✔
693
    return a
10,823,162✔
694
end
695

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

699
_similar_shape(itr, ::SizeUnknown) = nothing
1✔
700
_similar_shape(itr, ::HasLength) = length(itr)::Integer
33,210,718✔
701
_similar_shape(itr, ::HasShape) = axes(itr)
394,319,090✔
702

703
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,059,171✔
704
    similar(c, T, 0)
705
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
3,748,695✔
706
    similar(c, T, len)
707
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
140,527✔
708
    similar(c, T, axs)
709

710
# make a collection appropriate for collecting `itr::Generator`
711
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
487✔
712
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
26,844,925✔
713
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
394,378,307✔
714

715
# used by syntax lowering for simple typed comprehensions
716
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
418,148,467✔
717

718

719
"""
720
    collect(collection)
721

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

727
Used by comprehensions to turn a generator into an `Array`.
728

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

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

751
collect(A::AbstractArray) = _collect_indices(axes(A), A)
131,070✔
752

753
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
139,753✔
754

755
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
3,959,789✔
756
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
757

758
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,059,137✔
759
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,059,140✔
760
    for x in itr
2,117,275✔
761
        push!(a,x)
8,964,286✔
762
    end
15,262,517✔
763
    return a
1,059,136✔
764
end
765

766
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
767
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
174,476✔
768
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
769
function _collect_indices(indsA, A)
120✔
770
    B = Array{eltype(A)}(undef, length.(indsA))
120✔
771
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
120✔
772
end
773

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

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

817
function collect(itr::Generator)
569,565✔
818
    isz = IteratorSize(itr.iter)
70,252✔
819
    et = @default_eltype(itr)
×
820
    if isa(isz, SizeUnknown)
70,252✔
821
        return grow_to!(Vector{et}(), itr)
82,868✔
822
    else
823
        shp = _similar_shape(itr, isz)
486,968✔
824
        y = iterate(itr)
962,291✔
825
        if y === nothing
486,770✔
826
            return _array_for(et, isz, shp)
1,023✔
827
        end
828
        v1, st = y
68,694✔
829
        dest = _array_for(typeof(v1), isz, shp)
485,863✔
830
        # The typeassert gives inference a helping hand on the element type and dimensionality
831
        # (work-around for #28382)
832
        et′ = et <: Type ? Type : et
68,694✔
833
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
68,753✔
834
        collect_to_with_first!(dest, v1, itr, st)::RT
10,479,798✔
835
    end
836
end
837

838
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
34✔
839
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
840

841
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
139,390✔
842
    et = @default_eltype(itr)
126,948✔
843
    shp = _similar_shape(itr, isz)
139,391✔
844
    y = iterate(itr)
277,168✔
845
    if y === nothing
139,388✔
846
        return _similar_for(c, et, itr, isz, shp)
1,295✔
847
    end
848
    v1, st = y
125,870✔
849
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
138,109✔
850
    # The typeassert gives inference a helping hand on the element type and dimensionality
851
    # (work-around for #28382)
852
    et′ = et <: Type ? Type : et
125,828✔
853
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
125,847✔
854
    collect_to_with_first!(dest, v1, itr, st)::RT
138,484✔
855
end
856

857
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
194,604✔
858
    i1 = first(LinearIndices(dest))
194,522✔
859
    dest[i1] = v1
623,886✔
860
    return collect_to!(dest, itr, i1+1, st)
84,505,616✔
861
end
862

863
function collect_to_with_first!(dest, v1, itr, st)
×
864
    push!(dest, v1)
×
865
    return grow_to!(dest, itr, st)
×
866
end
867

868
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
403✔
869
    @inline
401✔
870
    new = similar(dest, promote_typejoin(T, typeof(el)))
407✔
871
    f = first(LinearIndices(dest))
401✔
872
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
801✔
873
    @inbounds new[i] = el
403✔
874
    return new
403✔
875
end
876

877
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
231,181✔
878
    # collect to dest array, checking the type of each result. if a result does not
879
    # match, widen the result type and re-dispatch.
880
    i = offs
194,925✔
881
    while true
86,241,891✔
882
        y = iterate(itr, st)
171,858,567✔
883
        y === nothing && break
86,241,884✔
884
        el, st = y
85,172,902✔
885
        if el isa T
85,171,577✔
886
            @inbounds dest[i] = el
85,624,773✔
887
            i += 1
85,617,602✔
888
        else
889
            new = setindex_widen_up_to(dest, el, i)
525✔
890
            return collect_to!(new, itr, i+1, st)
403✔
891
        end
892
    end
85,617,602✔
893
    return dest
623,879✔
894
end
895

896
function grow_to!(dest, itr)
1,163✔
897
    y = iterate(itr)
1,404✔
898
    y === nothing && return dest
1,164✔
899
    dest2 = empty(dest, typeof(y[1]))
263✔
900
    push!(dest2, y[1])
287✔
901
    grow_to!(dest2, itr, y[2])
247✔
902
end
903

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

917
function grow_to!(dest, itr, st)
300✔
918
    T = eltype(dest)
196✔
919
    y = iterate(itr, st)
548✔
920
    while y !== nothing
3,906✔
921
        el, st = y
2,348✔
922
        if el isa T
2,348✔
923
            push!(dest, el)
3,609✔
924
        else
925
            new = push_widen(dest, el)
55✔
926
            return grow_to!(new, itr, st)
53✔
927
        end
928
        y = iterate(itr, st)
5,526✔
929
    end
3,606✔
930
    return dest
247✔
931
end
932

933
## Iteration ##
934

935
iterate(A::Array, i=1) = (@inline; (i % UInt) - 1 < length(A) ? (@inbounds A[i], i + 1) : nothing)
9,008,827,660✔
936

937
## Indexing: getindex ##
938

939
"""
940
    getindex(collection, key...)
941

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

945
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
946

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

954
julia> getindex(A, "a")
955
1
956
```
957
"""
958
function getindex end
959

960
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
961
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
907,314✔
962
    @inline
866,026✔
963
    @boundscheck checkbounds(A, I)
54,126,550✔
964
    lI = length(I)
54,126,548✔
965
    X = similar(A, axes(I))
54,126,560✔
966
    if lI > 0
54,126,548✔
967
        copyto!(X, firstindex(X), A, first(I), lI)
48,384,446✔
968
    end
969
    return X
54,126,548✔
970
end
971

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

975
function getindex(A::Array, c::Colon)
4,805✔
976
    lI = length(A)
1,642,874✔
977
    X = similar(A, lI)
1,642,874✔
978
    if lI > 0
1,642,874✔
979
        unsafe_copyto!(X, 1, A, 1, lI)
1,642,872✔
980
    end
981
    return X
1,642,874✔
982
end
983

984
# This is redundant with the abstract fallbacks, but needed for bootstrap
985
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
3,165,753✔
986
    return S[ A[i] for i in I ]
13,042,406✔
987
end
988

989
## Indexing: setindex! ##
990

991
"""
992
    setindex!(collection, value, key...)
993

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

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

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

1011
@eval setindex!(A::Array{T}, x, i1::Int) where {T} =
17,001,493,089✔
1012
    arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1)
1013
@eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
54,907,795✔
1014
    (@inline; arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1, i2, I...))
59,349,107✔
1015

1016
__inbounds_setindex!(A::Array{T}, x, i1::Int) where {T} =
1,200,390,018✔
1017
    arrayset(false, A, convert(T,x)::T, i1)
1018
__inbounds_setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
×
1019
    (@inline; arrayset(false, A, convert(T,x)::T, i1, i2, I...))
×
1020

1021
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1022
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
810,484✔
1023
    @_propagate_inbounds_meta
810,484✔
1024
    @boundscheck setindex_shape_check(X, length(I))
5,806,164✔
1025
    require_one_based_indexing(X)
810,484✔
1026
    X′ = unalias(A, X)
814,843✔
1027
    I′ = unalias(A, I)
810,627✔
1028
    count = 1
810,484✔
1029
    for i in I′
10,847,458✔
1030
        @inbounds x = X′[count]
14,240,097✔
1031
        A[i] = x
14,242,180✔
1032
        count += 1
14,240,097✔
1033
    end
23,436,938✔
1034
    return A
5,806,164✔
1035
end
1036

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

1058
# efficiently grow an array
1059

1060
_growbeg!(a::Vector, delta::Integer) =
1,042,994✔
1061
    ccall(:jl_array_grow_beg, Cvoid, (Any, UInt), a, delta)
1062
_growend!(a::Vector, delta::Integer) =
1,477,274,498✔
1063
    ccall(:jl_array_grow_end, Cvoid, (Any, UInt), a, delta)
1064
_growat!(a::Vector, i::Integer, delta::Integer) =
65,169,294✔
1065
    ccall(:jl_array_grow_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1066

1067
# efficiently delete part of an array
1068

1069
_deletebeg!(a::Vector, delta::Integer) =
18,457,537✔
1070
    ccall(:jl_array_del_beg, Cvoid, (Any, UInt), a, delta)
1071
_deleteend!(a::Vector, delta::Integer) =
405,341,758✔
1072
    ccall(:jl_array_del_end, Cvoid, (Any, UInt), a, delta)
1073
_deleteat!(a::Vector, i::Integer, delta::Integer) =
306,195✔
1074
    ccall(:jl_array_del_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1075

1076
## Dequeue functionality ##
1077

1078
"""
1079
    push!(collection, items...) -> collection
1080

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

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

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

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

1102
See also [`pushfirst!`](@ref).
1103
"""
1104
function push! end
1105

1106
function push!(a::Vector{T}, item) where T
345,113✔
1107
    # convert first so we don't grow the array if the assignment won't work
1108
    itemT = item isa T ? item : convert(T, item)::T
23,130,220✔
1109
    _growend!(a, 1)
980,642,864✔
1110
    @_safeindex a[length(a)] = itemT
980,642,864✔
1111
    return a
9,443,413✔
1112
end
1113

1114
# specialize and optimize the single argument case
1115
function push!(a::Vector{Any}, @nospecialize x)
3,170,897✔
1116
    _growend!(a, 1)
83,057,374✔
1117
    @_safeindex a[length(a)] = x
83,057,373✔
1118
    return a
2,919,640✔
1119
end
1120
function push!(a::Vector{Any}, @nospecialize x...)
86,091✔
1121
    @_terminates_locally_meta
1✔
1122
    na = length(a)
86,091✔
1123
    nx = length(x)
1✔
1124
    _growend!(a, nx)
86,091✔
1125
    @_safeindex for i = 1:nx
86,091✔
1126
        a[na+i] = x[i]
176,645✔
1127
    end
258,275✔
1128
    return a
86,091✔
1129
end
1130

1131
"""
1132
    append!(collection, collections...) -> collection.
1133

1134
For an ordered container `collection`, add the elements of each `collections`
1135
to the end of it.
1136

1137
!!! compat "Julia 1.6"
1138
    Specifying multiple collections to be appended requires at least Julia 1.6.
1139

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

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

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

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

1164
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1165
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1166
"""
1167
function append!(a::Vector, items::AbstractVector)
72,657✔
1168
    itemindices = eachindex(items)
55,525,962✔
1169
    n = length(itemindices)
45,492✔
1170
    _growend!(a, n)
55,525,962✔
1171
    copyto!(a, length(a)-n+1, items, first(itemindices), n)
55,527,316✔
1172
    return a
55,525,962✔
1173
end
1174

1175
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
44,524,675✔
1176
push!(a::AbstractVector, iter...) = append!(a, iter)
3,967✔
1177

1178
append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
76✔
1179

1180
function _append!(a, ::Union{HasLength,HasShape}, iter)
16,292,081✔
1181
    @_terminates_locally_meta
1,849✔
1182
    n = length(a)
16,292,081✔
1183
    i = lastindex(a)
16,292,081✔
1184
    resize!(a, n+Int(length(iter))::Int)
26,762,305✔
1185
    @_safeindex for (i, item) in zip(i+1:lastindex(a), iter)
22,113,938✔
1186
        a[i] = item
23,641,339✔
1187
    end
41,457,469✔
1188
    a
16,292,081✔
1189
end
1190

1191
function _append!(a, ::IteratorSize, iter)
28,232,593✔
1192
    for item in iter
28,232,594✔
1193
        push!(a, item)
28,121,546✔
1194
    end
28,121,547✔
1195
    a
28,232,593✔
1196
end
1197

1198
"""
1199
    prepend!(a::Vector, collections...) -> collection
1200

1201
Insert the elements of each `collections` to the beginning of `a`.
1202

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

1206
!!! compat "Julia 1.6"
1207
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1208

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

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

1229
function prepend!(a::Vector, items::AbstractVector)
4,670✔
1230
    itemindices = eachindex(items)
4,670✔
1231
    n = length(itemindices)
4,630✔
1232
    _growbeg!(a, n)
4,670✔
1233
    if a === items
4,670✔
1234
        copyto!(a, 1, items, n+1, n)
×
1235
    else
1236
        copyto!(a, 1, items, first(itemindices), n)
4,824✔
1237
    end
1238
    return a
4,670✔
1239
end
1240

1241
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
4✔
1242
pushfirst!(a::Vector, iter...) = prepend!(a, iter)
4✔
1243

1244
prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
×
1245

1246
function _prepend!(a, ::Union{HasLength,HasShape}, iter)
2✔
1247
    @_terminates_locally_meta
2✔
1248
    require_one_based_indexing(a)
2✔
1249
    n = length(iter)
2✔
1250
    _growbeg!(a, n)
2✔
1251
    i = 0
2✔
1252
    for item in iter
2✔
1253
        @_safeindex a[i += 1] = item
4✔
1254
    end
6✔
1255
    a
2✔
1256
end
1257
function _prepend!(a, ::IteratorSize, iter)
×
1258
    n = 0
×
1259
    for item in iter
×
1260
        n += 1
×
1261
        pushfirst!(a, item)
×
1262
    end
×
1263
    reverse!(a, 1, n)
×
1264
    a
×
1265
end
1266

1267
"""
1268
    resize!(a::Vector, n::Integer) -> Vector
1269

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

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

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

1284
julia> length(a)
1285
8
1286

1287
julia> a[1:6]
1288
6-element Vector{Int64}:
1289
 6
1290
 5
1291
 4
1292
 3
1293
 2
1294
 1
1295
```
1296
"""
1297
function resize!(a::Vector, nl::Integer)
5,616,847✔
1298
    l = length(a)
534,116,363✔
1299
    if nl > l
534,116,363✔
1300
        _growend!(a, nl-l)
242,292,154✔
1301
    elseif nl != l
291,824,211✔
1302
        if nl < 0
64,229,601✔
1303
            _throw_argerror("new length must be ≥ 0")
1✔
1304
        end
1305
        _deleteend!(a, l-nl)
64,230,898✔
1306
    end
1307
    return a
534,116,362✔
1308
end
1309

1310
"""
1311
    sizehint!(s, n) -> s
1312

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

1318
See also [`resize!`](@ref).
1319

1320
# Notes on the performance model
1321

1322
For types that support `sizehint!`,
1323

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

1328
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1329
   `Base`.
1330

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

1335
function sizehint!(a::Vector, sz::Integer)
458,915✔
1336
    ccall(:jl_array_sizehint, Cvoid, (Any, UInt), a, sz)
171,472,043✔
1337
    a
619,462✔
1338
end
1339

1340
"""
1341
    pop!(collection) -> item
1342

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

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

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

1357
julia> pop!(A)
1358
3
1359

1360
julia> A
1361
2-element Vector{Int64}:
1362
 1
1363
 2
1364

1365
julia> S = Set([1, 2])
1366
Set{Int64} with 2 elements:
1367
  2
1368
  1
1369

1370
julia> pop!(S)
1371
2
1372

1373
julia> S
1374
Set{Int64} with 1 element:
1375
  1
1376

1377
julia> pop!(Dict(1=>2))
1378
1 => 2
1379
```
1380
"""
1381
function pop!(a::Vector)
60,061✔
1382
    if isempty(a)
279,736,759✔
1383
        _throw_argerror("array must be non-empty")
×
1384
    end
1385
    item = a[end]
279,736,759✔
1386
    _deleteend!(a, 1)
279,736,759✔
1387
    return item
279,736,759✔
1388
end
1389

1390
"""
1391
    popat!(a::Vector, i::Integer, [default])
1392

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

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

1400
!!! compat "Julia 1.5"
1401
    This function is available as of Julia 1.5.
1402

1403
# Examples
1404
```jldoctest
1405
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1406
3
1407

1408
julia> a
1409
3-element Vector{Int64}:
1410
 4
1411
 2
1412
 1
1413

1414
julia> popat!(a, 4, missing)
1415
missing
1416

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

1428
function popat!(a::Vector, i::Integer, default)
×
1429
    if 1 <= i <= length(a)
×
1430
        x = @inbounds a[i]
×
1431
        _deleteat!(a, i, 1)
×
1432
        x
×
1433
    else
1434
        default
×
1435
    end
1436
end
1437

1438
"""
1439
    pushfirst!(collection, items...) -> collection
1440

1441
Insert one or more `items` at the beginning of `collection`.
1442

1443
This function is called `unshift` in many other programming languages.
1444

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

1464
# specialize and optimize the single argument case
1465
function pushfirst!(a::Vector{Any}, @nospecialize x)
114✔
1466
    _growbeg!(a, 1)
738,916✔
1467
    @_safeindex a[1] = x
738,916✔
1468
    return a
112✔
1469
end
1470
function pushfirst!(a::Vector{Any}, @nospecialize x...)
762✔
1471
    @_terminates_locally_meta
1✔
1472
    na = length(a)
1✔
1473
    nx = length(x)
1✔
1474
    _growbeg!(a, nx)
762✔
1475
    @_safeindex for i = 1:nx
762✔
1476
        a[i] = x[i]
1,525✔
1477
    end
2,288✔
1478
    return a
762✔
1479
end
1480

1481
"""
1482
    popfirst!(collection) -> item
1483

1484
Remove the first `item` from `collection`.
1485

1486
This function is called `shift` in many other programming languages.
1487

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

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

1501
julia> popfirst!(A)
1502
1
1503

1504
julia> A
1505
5-element Vector{Int64}:
1506
 2
1507
 3
1508
 4
1509
 5
1510
 6
1511
```
1512
"""
1513
function popfirst!(a::Vector)
1,036,691✔
1514
    if isempty(a)
18,424,938✔
1515
        _throw_argerror("array must be non-empty")
×
1516
    end
1517
    item = a[1]
18,424,940✔
1518
    _deletebeg!(a, 1)
18,424,940✔
1519
    return item
18,424,940✔
1520
end
1521

1522
"""
1523
    insert!(a::Vector, index::Integer, item)
1524

1525
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1526
the resulting `a`.
1527

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

1530
# Examples
1531
```jldoctest
1532
julia> insert!(Any[1:6;], 3, "here")
1533
7-element Vector{Any}:
1534
 1
1535
 2
1536
  "here"
1537
 3
1538
 4
1539
 5
1540
 6
1541
```
1542
"""
1543
function insert!(a::Array{T,1}, i::Integer, item) where T
301,825✔
1544
    # Throw convert error before changing the shape of the array
1545
    _item = item isa T ? item : convert(T, item)::T
301,820✔
1546
    _growat!(a, i, 1)
65,144,768✔
1547
    # _growat! already did bound check
1548
    @inbounds a[i] = _item
65,144,764✔
1549
    return a
301,821✔
1550
end
1551

1552
"""
1553
    deleteat!(a::Vector, i::Integer)
1554

1555
Remove the item at the given `i` and return the modified `a`. Subsequent items
1556
are shifted to fill the resulting gap.
1557

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

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

1577
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
75,544✔
1578
    if eltype(r) === Bool
75,544✔
1579
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1580
    else
1581
        n = length(a)
75,538✔
1582
        f = first(r)
75,633✔
1583
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
75,538✔
1584
        isempty(r) || _deleteat!(a, f, length(r))
164,953✔
1585
        return a
84,288✔
1586
    end
1587
end
1588

1589
"""
1590
    deleteat!(a::Vector, inds)
1591

1592
Remove the items at the indices given by `inds`, and return the modified `a`.
1593
Subsequent items are shifted to fill the resulting gap.
1594

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

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

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

1612
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1613
ERROR: ArgumentError: indices must be unique and sorted
1614
Stacktrace:
1615
[...]
1616
```
1617
"""
1618
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
×
1619
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
85,962✔
1620

1621
struct Nowhere; end
1622
push!(::Nowhere, _) = nothing
1,491,786✔
1623
_growend!(::Nowhere, _) = nothing
×
1624

1625
@inline function _push_deleted!(dltd, a::Vector, ind)
1,491,786✔
1626
    if @inbounds isassigned(a, ind)
1,547,089✔
1627
        push!(dltd, @inbounds a[ind])
1,547,103✔
1628
    else
1629
        _growend!(dltd, 1)
×
1630
    end
1631
end
1632

1633
@inline function _copy_item!(a::Vector, p, q)
4,377,171✔
1634
    if @inbounds isassigned(a, q)
4,402,863✔
1635
        @inbounds a[p] = a[q]
4,402,884✔
1636
    else
1637
        _unsetindex!(a, p)
×
1638
    end
1639
end
1640

1641
function _deleteat!(a::Vector, inds, dltd=Nowhere())
121,636✔
1642
    n = length(a)
171,924✔
1643
    y = iterate(inds)
86,193✔
1644
    y === nothing && return a
85,962✔
1645
    (p, s) = y
35,443✔
1646
    checkbounds(a, p)
85,731✔
1647
    _push_deleted!(dltd, a, p)
85,735✔
1648
    q = p+1
85,731✔
1649
    while true
1,547,089✔
1650
        y = iterate(inds, s)
1,632,820✔
1651
        y === nothing && break
1,547,089✔
1652
        (i,s) = y
1,456,343✔
1653
        if !(q <= i <= n)
1,461,358✔
1654
            if i < q
×
1655
                _throw_argerror("indices must be unique and sorted")
×
1656
            else
1657
                throw(BoundsError())
×
1658
            end
1659
        end
1660
        while q < i
2,885,874✔
1661
            _copy_item!(a, p, q)
1,424,530✔
1662
            p += 1; q += 1
2,849,032✔
1663
        end
1,424,516✔
1664
        _push_deleted!(dltd, a, i)
1,461,368✔
1665
        q = i+1
1,461,358✔
1666
    end
1,461,358✔
1667
    while q <= n
3,022,074✔
1668
        _copy_item!(a, p, q)
2,936,350✔
1669
        p += 1; q += 1
5,872,686✔
1670
    end
2,936,343✔
1671
    _deleteend!(a, n-p+1)
85,731✔
1672
    return a
85,731✔
1673
end
1674

1675
# Simpler and more efficient version for logical indexing
1676
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,006✔
1677
    n = length(a)
4,006✔
1678
    length(inds) == n || throw(BoundsError(a, inds))
4,008✔
1679
    p = 1
4,004✔
1680
    for (q, i) in enumerate(inds)
8,008✔
1681
        _copy_item!(a, p, q)
42,004✔
1682
        p += !i
42,004✔
1683
    end
80,004✔
1684
    _deleteend!(a, n-p+1)
4,004✔
1685
    return a
4,004✔
1686
end
1687

1688
const _default_splice = []
1689

1690
"""
1691
    splice!(a::Vector, index::Integer, [replacement]) -> item
1692

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

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

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

1705
julia> A
1706
5-element Vector{Int64}:
1707
 6
1708
 5
1709
 4
1710
 3
1711
 1
1712

1713
julia> splice!(A, 5, -1)
1714
1
1715

1716
julia> A
1717
5-element Vector{Int64}:
1718
  6
1719
  5
1720
  4
1721
  3
1722
 -1
1723

1724
julia> splice!(A, 1, [-1, -2, -3])
1725
6
1726

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

1738
To insert `replacement` before an index `n` without removing any items, use
1739
`splice!(collection, n:n-1, replacement)`.
1740
"""
1741
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,682✔
1742
    v = a[i]
3,692✔
1743
    m = length(ins)
3,406✔
1744
    if m == 0
3,406✔
1745
        _deleteat!(a, i, 1)
546✔
1746
    elseif m == 1
2,860✔
1747
        a[i] = ins[1]
262✔
1748
    else
1749
        _growat!(a, i, m-1)
2,598✔
1750
        k = 1
2,598✔
1751
        for x in ins
2,598✔
1752
            a[i+k-1] = x
334,315✔
1753
            k += 1
334,315✔
1754
        end
334,315✔
1755
    end
1756
    return v
3,406✔
1757
end
1758

1759
"""
1760
    splice!(a::Vector, indices, [replacement]) -> items
1761

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

1768
To insert `replacement` before an index `n` without removing any items, use
1769
`splice!(collection, n:n-1, replacement)`.
1770

1771
!!! compat "Julia 1.5"
1772
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1773

1774
!!! compat "Julia 1.8"
1775
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1776

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

1782
julia> A
1783
8-element Vector{Int64}:
1784
 -1
1785
 -2
1786
 -3
1787
  2
1788
  5
1789
  4
1790
  3
1791
 -1
1792
```
1793
"""
1794
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
105,710✔
1795
    v = a[r]
105,718✔
1796
    m = length(ins)
71,772✔
1797
    if m == 0
71,772✔
1798
        deleteat!(a, r)
74,225✔
1799
        return v
37,171✔
1800
    end
1801

1802
    n = length(a)
34,601✔
1803
    f = first(r)
34,601✔
1804
    l = last(r)
34,601✔
1805
    d = length(r)
34,601✔
1806

1807
    if m < d
34,601✔
1808
        delta = d - m
12,581✔
1809
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
18,976✔
1810
    elseif m > d
22,020✔
1811
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
21,914✔
1812
    end
1813

1814
    k = 1
34,518✔
1815
    for x in ins
46,107✔
1816
        a[f+k-1] = x
5,381,270✔
1817
        k += 1
4,036,752✔
1818
    end
5,405,260✔
1819
    return v
34,601✔
1820
end
1821

1822
splice!(a::Vector, inds) = (dltds = eltype(a)[]; _deleteat!(a, inds, dltds); dltds)
×
1823

1824
function empty!(a::Vector)
79,830✔
1825
    _deleteend!(a, length(a))
61,166,322✔
1826
    return a
61,166,322✔
1827
end
1828

1829
_memcmp(a, b, len) = ccall(:memcmp, Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), a, b, len % Csize_t) % Int
71,416✔
1830

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

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

1842
# this is ~20% faster than the generic implementation above for very small arrays
1843
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
7,450✔
1844
    len = length(a)
45,897✔
1845
    len == length(b) && 0 == _memcmp(a, b, sizeof(eltype(Arr)) * len)
45,899✔
1846
end
1847

1848
"""
1849
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
1850

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

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

1864
julia> reverse(A)
1865
5-element Vector{Int64}:
1866
 5
1867
 4
1868
 3
1869
 2
1870
 1
1871

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

1880
julia> reverse(A, 3, 5)
1881
5-element Vector{Int64}:
1882
 1
1883
 2
1884
 5
1885
 4
1886
 3
1887
```
1888
"""
1889
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
5,277✔
1890
    s, n = Int(start), Int(stop)
561✔
1891
    B = similar(A)
5,278✔
1892
    for i = firstindex(A):s-1
5,277✔
1893
        B[i] = A[i]
×
1894
    end
×
1895
    for i = s:n
10,546✔
1896
        B[i] = A[n+s-i]
244,834✔
1897
    end
484,395✔
1898
    for i = n+1:lastindex(A)
5,277✔
1899
        B[i] = A[i]
×
1900
    end
×
1901
    return B
5,277✔
1902
end
1903

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

1917
function reverseind(a::AbstractVector, i::Integer)
×
1918
    li = LinearIndices(a)
×
1919
    first(li) + last(li) - i
×
1920
end
1921

1922
# This implementation of `midpoint` is performance-optimized but safe
1923
# only if `lo <= hi`.
1924
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
3,356,197✔
1925
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
1926

1927
"""
1928
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
1929

1930
In-place version of [`reverse`](@ref).
1931

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

1942
julia> reverse!(A);
1943

1944
julia> A
1945
5-element Vector{Int64}:
1946
 5
1947
 4
1948
 3
1949
 2
1950
 1
1951
```
1952
"""
1953
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
62,340✔
1954
    s, n = Int(start), Int(stop)
2,582✔
1955
    if n > s # non-empty and non-trivial
62,338✔
1956
        liv = LinearIndices(v)
59,539✔
1957
        if !(first(liv) ≤ s ≤ last(liv))
59,539✔
1958
            throw(BoundsError(v, s))
2✔
1959
        elseif !(first(liv) ≤ n ≤ last(liv))
59,537✔
1960
            throw(BoundsError(v, n))
×
1961
        end
1962
        r = n
2,230✔
1963
        @inbounds for i in s:midpoint(s, n-1)
119,074✔
1964
            v[i], v[r] = v[r], v[i]
1,560,177✔
1965
            r -= 1
1,560,177✔
1966
        end
3,060,817✔
1967
    end
1968
    return v
62,336✔
1969
end
1970

1971
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
1972

1973
vcat() = Vector{Any}()
10,408✔
1974
hcat() = Vector{Any}()
1✔
1975

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

1987
function vcat(arrays::Vector{T}...) where T
35,779✔
1988
    n = 0
6,933✔
1989
    for a in arrays
35,779✔
1990
        n += length(a)
2,071,651✔
1991
    end
2,107,411✔
1992
    arr = Vector{T}(undef, n)
35,779✔
1993
    nd = 1
6,933✔
1994
    for a in arrays
35,779✔
1995
        na = length(a)
2,071,651✔
1996
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,071,651✔
1997
        unsafe_copyto!(arr, nd, a, 1, na)
2,071,651✔
1998
        nd += na
2,071,651✔
1999
    end
2,107,411✔
2000
    return arr
35,779✔
2001
end
2002
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
44✔
2003

2004
# disambiguation with LinAlg/special.jl
2005
# Union{Number,Vector,Matrix} is for LinearAlgebra._DenseConcatGroup
2006
# VecOrMat{T} is for LinearAlgebra._TypedDenseConcatGroup
2007
hcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(2))
24✔
2008
hcat(A::VecOrMat{T}...) where {T} = typed_hcat(T, A...)
120✔
2009
vcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(1))
90✔
2010
vcat(A::VecOrMat{T}...) where {T} = typed_vcat(T, A...)
496✔
2011
hvcat(rows::Tuple{Vararg{Int}}, xs::Union{Number,Vector,Matrix}...) =
11✔
2012
    typed_hvcat(promote_eltypeof(xs...), rows, xs...)
2013
hvcat(rows::Tuple{Vararg{Int}}, xs::VecOrMat{T}...) where {T} =
9✔
2014
    typed_hvcat(T, rows, xs...)
2015

2016
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))
×
2017

2018
## find ##
2019

2020
"""
2021
    findnext(A, i)
2022

2023
Find the next index after or including `i` of a `true` element of `A`,
2024
or `nothing` if not found.
2025

2026
Indices are of the same type as those returned by [`keys(A)`](@ref)
2027
and [`pairs(A)`](@ref).
2028

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

2038
julia> findnext(A, 1)
2039
3
2040

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

2043
julia> A = [false false; true false]
2044
2×2 Matrix{Bool}:
2045
 0  0
2046
 1  0
2047

2048
julia> findnext(A, CartesianIndex(1, 1))
2049
CartesianIndex(2, 1)
2050
```
2051
"""
2052
findnext(A, start) = findnext(identity, A, start)
77,674✔
2053

2054
"""
2055
    findfirst(A)
2056

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

2061
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2062
and [`pairs(A)`](@ref).
2063

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

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

2075
julia> findfirst(A)
2076
3
2077

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

2080
julia> A = [false false; true false]
2081
2×2 Matrix{Bool}:
2082
 0  0
2083
 1  0
2084

2085
julia> findfirst(A)
2086
CartesianIndex(2, 1)
2087
```
2088
"""
2089
findfirst(A) = findfirst(identity, A)
×
2090

2091
# Needed for bootstrap, and allows defining only an optimized findnext method
2092
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
11,791✔
2093

2094
"""
2095
    findnext(predicate::Function, A, i)
2096

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

2100
Indices are of the same type as those returned by [`keys(A)`](@ref)
2101
and [`pairs(A)`](@ref).
2102

2103
# Examples
2104
```jldoctest
2105
julia> A = [1, 4, 2, 2];
2106

2107
julia> findnext(isodd, A, 1)
2108
1
2109

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

2112
julia> A = [1 4; 2 2];
2113

2114
julia> findnext(isodd, A, CartesianIndex(1, 1))
2115
CartesianIndex(1, 1)
2116
```
2117
"""
2118
function findnext(testf::Function, A, start)
47,627✔
2119
    i = oftype(first(keys(A)), start)
45,575✔
2120
    l = last(keys(A))
39,391,627✔
2121
    i > l && return nothing
39,391,627✔
2122
    while true
151,094,109✔
2123
        testf(A[i]) && return i
151,097,980✔
2124
        i == l && break
150,678,233✔
2125
        # nextind(A, l) can throw/overflow
2126
        i = nextind(A, i)
146,705,779✔
2127
    end
146,705,761✔
2128
    return nothing
3,972,450✔
2129
end
2130

2131
"""
2132
    findfirst(predicate::Function, A)
2133

2134
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2135
Return `nothing` if there is no such element.
2136

2137
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2138
and [`pairs(A)`](@ref).
2139

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

2149
julia> findfirst(iseven, A)
2150
2
2151

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

2154
julia> findfirst(isequal(4), A)
2155
2
2156

2157
julia> A = [1 4; 2 2]
2158
2×2 Matrix{Int64}:
2159
 1  4
2160
 2  2
2161

2162
julia> findfirst(iseven, A)
2163
CartesianIndex(2, 1)
2164
```
2165
"""
2166
function findfirst(testf::Function, A)
8✔
2167
    for (i, a) in pairs(A)
11✔
2168
        testf(a) && return i
8✔
2169
    end
7✔
2170
    return nothing
4✔
2171
end
2172

2173
# Needed for bootstrap, and allows defining only an optimized findnext method
2174
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
190,652,244✔
2175
    findnext(testf, A, first(keys(A)))
2176

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

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

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

2191
"""
2192
    findprev(A, i)
2193

2194
Find the previous index before or including `i` of a `true` element of `A`,
2195
or `nothing` if not found.
2196

2197
Indices are of the same type as those returned by [`keys(A)`](@ref)
2198
and [`pairs(A)`](@ref).
2199

2200
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2201

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

2211
julia> findprev(A, 3)
2212
3
2213

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

2216
julia> A = [false false; true true]
2217
2×2 Matrix{Bool}:
2218
 0  0
2219
 1  1
2220

2221
julia> findprev(A, CartesianIndex(2, 1))
2222
CartesianIndex(2, 1)
2223
```
2224
"""
2225
findprev(A, start) = findprev(identity, A, start)
12,279✔
2226

2227
"""
2228
    findlast(A)
2229

2230
Return the index or key of the last `true` value in `A`.
2231
Return `nothing` if there is no `true` value in `A`.
2232

2233
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2234
and [`pairs(A)`](@ref).
2235

2236
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2237

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

2247
julia> findlast(A)
2248
3
2249

2250
julia> A = falses(2,2);
2251

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

2254
julia> A = [true false; true false]
2255
2×2 Matrix{Bool}:
2256
 1  0
2257
 1  0
2258

2259
julia> findlast(A)
2260
CartesianIndex(2, 1)
2261
```
2262
"""
2263
findlast(A) = findlast(identity, A)
22✔
2264

2265
# Needed for bootstrap, and allows defining only an optimized findprev method
2266
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
4,081✔
2267

2268
"""
2269
    findprev(predicate::Function, A, i)
2270

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

2274
Indices are of the same type as those returned by [`keys(A)`](@ref)
2275
and [`pairs(A)`](@ref).
2276

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

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

2288
julia> findprev(isodd, A, 3)
2289
3
2290

2291
julia> A = [4 6; 1 2]
2292
2×2 Matrix{Int64}:
2293
 4  6
2294
 1  2
2295

2296
julia> findprev(isodd, A, CartesianIndex(1, 2))
2297
CartesianIndex(2, 1)
2298
```
2299
"""
2300
function findprev(testf::Function, A, start)
36,691✔
2301
    f = first(keys(A))
36,691✔
2302
    i = oftype(f, start)
36,698✔
2303
    i < f && return nothing
38,228✔
2304
    while true
185,039✔
2305
        testf(A[i]) && return i
185,082✔
2306
        i == f && break
146,893✔
2307
        # prevind(A, f) can throw/underflow
2308
        i = prevind(A, i)
146,838✔
2309
    end
146,812✔
2310
    return nothing
53✔
2311
end
2312

2313
"""
2314
    findlast(predicate::Function, A)
2315

2316
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2317
Return `nothing` if there is no such element.
2318

2319
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2320
and [`pairs(A)`](@ref).
2321

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

2331
julia> findlast(isodd, A)
2332
3
2333

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

2336
julia> A = [1 2; 3 4]
2337
2×2 Matrix{Int64}:
2338
 1  2
2339
 3  4
2340

2341
julia> findlast(isodd, A)
2342
CartesianIndex(2, 1)
2343
```
2344
"""
2345
function findlast(testf::Function, A)
3✔
2346
    for (i, a) in Iterators.reverse(pairs(A))
3✔
2347
        testf(a) && return i
5✔
2348
    end
5✔
2349
    return nothing
1✔
2350
end
2351

2352
# Needed for bootstrap, and allows defining only an optimized findprev method
2353
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
12,667✔
2354
    findprev(testf, A, last(keys(A)))
2355

2356
"""
2357
    findall(f::Function, A)
2358

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

2362
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2363
and [`pairs(A)`](@ref).
2364

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

2373
julia> findall(isodd, x)
2374
2-element Vector{Int64}:
2375
 1
2376
 2
2377

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

2387
julia> findall(!iszero, A)
2388
4-element Vector{CartesianIndex{2}}:
2389
 CartesianIndex(1, 1)
2390
 CartesianIndex(2, 1)
2391
 CartesianIndex(1, 2)
2392
 CartesianIndex(2, 2)
2393

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

2400
julia> findall(x -> x >= 0, d)
2401
2-element Vector{Symbol}:
2402
 :A
2403
 :C
2404

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

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

2417
"""
2418
    findall(A)
2419

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

2424
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2425
and [`pairs(A)`](@ref).
2426

2427
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2428

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

2438
julia> findall(A)
2439
2-element Vector{Int64}:
2440
 1
2441
 4
2442

2443
julia> A = [true false; false true]
2444
2×2 Matrix{Bool}:
2445
 1  0
2446
 0  1
2447

2448
julia> findall(A)
2449
2-element Vector{CartesianIndex{2}}:
2450
 CartesianIndex(1, 1)
2451
 CartesianIndex(2, 2)
2452

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

2461
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2462
function _findall(f::Function, A::AbstractArray{Bool})
2,827✔
2463
    n = count(f, A)
2,829✔
2464
    I = Vector{eltype(keys(A))}(undef, n)
2,827✔
2465
    isempty(I) && return I
2,827✔
2466
    _findall(f, I, A)
2,458✔
2467
end
2468

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

2482
function _findall(f::Function, I::Vector, A::AbstractVector{Bool})
2,435✔
2483
    i = firstindex(A)
2,435✔
2484
    cnt = 1
2,435✔
2485
    len = length(I)
2,435✔
2486
    while cnt ≤ len
89,280✔
2487
        @inbounds I[cnt] = i
86,845✔
2488
        cnt += f(@inbounds A[i])
86,845✔
2489
        i = nextind(A, i)
86,845✔
2490
    end
86,845✔
2491
    cnt - 1 == len ? I : resize!(I, cnt - 1)
2,435✔
2492
end
2493

2494
findall(f::Function, A::AbstractArray{Bool}) = _findall(f, A)
2✔
2495
findall(f::Fix2{typeof(in)}, A::AbstractArray{Bool}) = _findall(f, A)
×
2496
findall(A::AbstractArray{Bool}) = _findall(identity, A)
4,732✔
2497

2498
findall(x::Bool) = x ? [1] : Vector{Int}()
×
2499
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
×
2500
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
×
2501

2502
# similar to Matlab's ismember
2503
"""
2504
    indexin(a, b)
2505

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

2510
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2511

2512
# Examples
2513
```jldoctest
2514
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2515

2516
julia> b = ['a', 'b', 'c'];
2517

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

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

2545
function _findin(a::Union{AbstractArray, Tuple}, b)
364✔
2546
    ind  = Vector{eltype(keys(a))}()
550✔
2547
    bset = Set(b)
364✔
2548
    @inbounds for (i,ai) in pairs(a)
585✔
2549
        ai in bset && push!(ind, i)
90,472✔
2550
    end
180,477✔
2551
    ind
364✔
2552
end
2553

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

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

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

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

2634
## Filter ##
2635

2636
"""
2637
    filter(f, a)
2638

2639
Return a copy of collection `a`, removing elements for which `f` is `false`.
2640
The function `f` is passed one argument.
2641

2642
!!! compat "Julia 1.4"
2643
    Support for `a` as a tuple requires at least Julia 1.4.
2644

2645
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2646

2647
# Examples
2648
```jldoctest
2649
julia> a = 1:10
2650
1:10
2651

2652
julia> filter(isodd, a)
2653
5-element Vector{Int64}:
2654
 1
2655
 3
2656
 5
2657
 7
2658
 9
2659
```
2660
"""
2661
function filter(f, a::Array{T, N}) where {T, N}
443,939✔
2662
    j = 1
443,086✔
2663
    b = Vector{T}(undef, length(a))
443,939✔
2664
    for ai in a
443,956✔
2665
        @inbounds b[j] = ai
1,400,919✔
2666
        j = ifelse(f(ai)::Bool, j+1, j)
1,405,959✔
2667
    end
1,844,756✔
2668
    resize!(b, j-1)
887,877✔
2669
    sizehint!(b, length(b))
443,939✔
2670
    b
443,939✔
2671
end
2672

2673
function filter(f, a::AbstractArray)
369✔
2674
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
369✔
2675

2676
    j = 1
369✔
2677
    idxs = Vector{Int}(undef, length(a))
372✔
2678
    for idx in eachindex(a)
609✔
2679
        @inbounds idxs[j] = idx
103,200✔
2680
        ai = @inbounds a[idx]
103,200✔
2681
        j = ifelse(f(ai)::Bool, j+1, j)
137,256✔
2682
    end
206,159✔
2683
    resize!(idxs, j-1)
736✔
2684
    res = a[idxs]
368✔
2685
    empty!(idxs)
368✔
2686
    sizehint!(idxs, 0)
368✔
2687
    return res
368✔
2688
end
2689

2690
"""
2691
    filter!(f, a)
2692

2693
Update collection `a`, removing elements for which `f` is `false`.
2694
The function `f` is passed one argument.
2695

2696
# Examples
2697
```jldoctest
2698
julia> filter!(isodd, Vector(1:10))
2699
5-element Vector{Int64}:
2700
 1
2701
 3
2702
 5
2703
 7
2704
 9
2705
```
2706
"""
2707
function filter!(f, a::AbstractVector)
937,326✔
2708
    j = firstindex(a)
1,025✔
2709
    for ai in a
960,158✔
2710
        @inbounds a[j] = ai
3,342,307✔
2711
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
6,294,657✔
2712
    end
4,256,801✔
2713
    j > lastindex(a) && return a
937,326✔
2714
    if a isa Vector
470✔
2715
        resize!(a, j-1)
320,274✔
2716
        sizehint!(a, j-1)
160,137✔
2717
    else
2718
        deleteat!(a, j:lastindex(a))
×
2719
    end
2720
    return a
160,137✔
2721
end
2722

2723
"""
2724
    filter(f)
2725

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

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

2732
# Examples
2733
```jldoctest
2734
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2735
(1, 2, 4, 6)
2736

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

2750
"""
2751
    keepat!(a::Vector, inds)
2752
    keepat!(a::BitVector, inds)
2753

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

2758
`inds` must be an iterator of sorted and unique integer indices.
2759
See also [`deleteat!`](@ref).
2760

2761
!!! compat "Julia 1.7"
2762
    This function is available as of Julia 1.7.
2763

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

2775
"""
2776
    keepat!(a::Vector, m::AbstractVector{Bool})
2777
    keepat!(a::BitVector, m::AbstractVector{Bool})
2778

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

2783
# Examples
2784
```jldoctest
2785
julia> a = [:a, :b, :c];
2786

2787
julia> keepat!(a, [true, false, true])
2788
2-element Vector{Symbol}:
2789
 :a
2790
 :c
2791

2792
julia> a
2793
2-element Vector{Symbol}:
2794
 :a
2795
 :c
2796
```
2797
"""
2798
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
×
2799

2800
# set-like operators for vectors
2801
# These are moderately efficient, preserve order, and remove dupes.
2802

2803
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
10,438✔
2804
    # P, U force specialization
2805
    if pred(x, state)
9,380✔
2806
        update!(state, x)
3,541✔
2807
        true
3,541✔
2808
    else
2809
        false
5,726✔
2810
    end
2811
end
2812

2813
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
243✔
2814
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
982✔
2815

2816
function _grow!(pred!, v::AbstractVector, itrs)
258✔
2817
    filter!(pred!, v) # uniquify v
260✔
2818
    for itr in itrs
260✔
2819
        mapfilter(pred!, push!, itr, v)
504✔
2820
    end
750✔
2821
    return v
260✔
2822
end
2823

2824
union!(v::AbstractVector{T}, itrs...) where {T} =
237✔
2825
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
2826

2827
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
23✔
2828
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
2829

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

2837
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
2838
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
2839

2840
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
960✔
2841

2842
function _shrink(shrinker!::F, itr, itrs) where F
900✔
2843
    T = promote_eltype(itr, itrs...)
822✔
2844
    keep = shrinker!(Set{T}(itr), itrs...)
909✔
2845
    vectorfilter(T, _shrink_filter!(keep), itr)
900✔
2846
end
2847

2848
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
461✔
2849
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
439✔
2850

2851
function intersect(v::AbstractVector, r::AbstractRange)
55✔
2852
    T = promote_eltype(v, r)
7✔
2853
    common = Iterators.filter(in(r), v)
59✔
2854
    seen = Set{T}(common)
59✔
2855
    return vectorfilter(T, _shrink_filter!(seen), common)
59✔
2856
end
2857
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
3✔
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

© 2026 Coveralls, Inc