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

JuliaLang / julia / #37649

12 Oct 2023 05:15AM UTC coverage: 87.56% (+0.9%) from 86.678%
#37649

push

local

web-flow
Reinstate load-time Pkg.precompile (#51672)

5 of 5 new or added lines in 1 file covered. (100.0%)

72441 of 82733 relevant lines covered (87.56%)

12848798.04 hits per line

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

93.82
/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::AbstractString
13,333✔
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}()
27,693,863✔
161
function vect(X::T...) where T
161,646✔
162
    @_terminates_locally_meta
81,143✔
163
    vec = Vector{T}(undef, length(X))
1,433,544✔
164
    @_safeindex for i = 1:length(X)
256,860✔
165
        vec[i] = X[i]
4,554,241✔
166
    end
6,404,917✔
167
    return vec
163,528✔
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...)
56,469✔
186
    T = promote_typeof(X...)
56,469✔
187
    return T[X...]
56,674✔
188
end
189

190
size(a::Array, d::Integer) = arraysize(a, d isa Int ? d : convert(Int, d))
3,071,957✔
191
size(a::Vector) = (arraysize(a,1),)
2,147,483,647✔
192
size(a::Matrix) = (arraysize(a,1), arraysize(a,2))
6,517,206✔
193
size(a::Array{<:Any,N}) where {N} = (@inline; ntuple(M -> size(a, M), Val(N))::Dims)
2,782,946✔
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))
3,936,426✔
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,353✔
214
isbitsunion(x) = false
22,425✔
215

216
function _unsetindex!(A::Array{T}, i::Int) where {T}
74,044✔
217
    @inline
5,872✔
218
    @boundscheck checkbounds(A, i)
6,199,692✔
219
    t = @_gc_preserve_begin A
6,200,329✔
220
    p = Ptr{Ptr{Cvoid}}(pointer(A, i))
6,200,263✔
221
    if !allocatedinline(T)
5,872✔
222
        Intrinsics.atomic_pointerset(p, C_NULL, :monotonic)
5,935,548✔
223
    elseif T isa DataType
5,105✔
224
        if !datatype_pointerfree(T)
5,103✔
225
            for j = 1:Core.sizeof(Ptr{Cvoid}):Core.sizeof(T)
11,637✔
226
                Intrinsics.atomic_pointerset(p + j - 1, C_NULL, :monotonic)
11,734✔
227
            end
19,959✔
228
        end
229
    end
230
    @_gc_preserve_end t
6,199,774✔
231
    return A
6,198,641✔
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,910,661✔
256
function elsize(::Type{Ptr{T}}) where T
8✔
257
    # this only must return something valid for values which satisfy is_valid_intrinsic_elptr(T),
258
    # which includes Any and most concrete datatypes
259
    T === Any && return sizeof(Ptr{Any})
8✔
260
    T isa DataType || sizeof(Any) # throws
7✔
261
    return LLT_ALIGN(Core.sizeof(T), datatype_alignment(T))
5✔
262
end
263
elsize(::Type{Union{}}, slurp...) = 0
×
264
sizeof(a::Array) = Core.sizeof(a)
3,365,473✔
265

266
function isassigned(a::Array, i::Int...)
12,996,716✔
267
    @inline
7,424,016✔
268
    @boundscheck checkbounds(Bool, a, i...) || return false
2,147,483,647✔
269
    ii = (_sub2ind(size(a), i...) % UInt) - 1
2,147,483,647✔
270
    ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii) == 1
2,147,483,647✔
271
end
272

273
## copy ##
274

275
"""
276
    unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
277

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

281
The `unsafe` prefix on this function indicates that no validation is performed on the
282
pointers `dest` and `src` to ensure that they are valid. Incorrect usage may corrupt or
283
segfault your program, in the same manner as C.
284
"""
285
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
15,665,286✔
286
    # Do not use this to copy data between pointer arrays.
287
    # It can't be made safe no matter how carefully you checked.
288
    memmove(dest, src, n * aligned_sizeof(T))
35,376,549✔
289
    return dest
34,733,396✔
290
end
291

292

293
function _unsafe_copyto!(dest, doffs, src, soffs, n)
37,955,156✔
294
    destp = pointer(dest, doffs)
37,955,156✔
295
    srcp = pointer(src, soffs)
37,955,156✔
296
    @inbounds if destp < srcp || destp > srcp + n
59,880,872✔
297
        for i = 1:n
75,910,310✔
298
            if isassigned(src, soffs + i - 1)
281,745,815✔
299
                dest[doffs + i - 1] = src[soffs + i - 1]
285,311,633✔
300
            else
301
                _unsetindex!(dest, doffs + i - 1)
×
302
            end
303
        end
525,536,235✔
304
    else
305
        for i = n:-1:1
×
306
            if isassigned(src, soffs + i - 1)
×
307
                dest[doffs + i - 1] = src[soffs + i - 1]
×
308
            else
309
                _unsetindex!(dest, doffs + i - 1)
×
310
            end
311
        end
×
312
    end
313
    return dest
37,954,915✔
314
end
315

316
"""
317
    unsafe_copyto!(dest::Array, do, src::Array, so, N)
318

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

322
The `unsafe` prefix on this function indicates that no validation is performed to ensure
323
that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
324
the same manner as C.
325
"""
326
function unsafe_copyto!(dest::Array{T}, doffs, src::Array{T}, soffs, n) where T
4,327,936✔
327
    t1 = @_gc_preserve_begin dest
194,644,634✔
328
    t2 = @_gc_preserve_begin src
194,644,634✔
329
    destp = pointer(dest, doffs)
194,644,634✔
330
    srcp = pointer(src, soffs)
194,644,645✔
331
    if !allocatedinline(T)
4,325,368✔
332
        ccall(:jl_array_ptr_copy, Cvoid, (Any, Ptr{Cvoid}, Any, Ptr{Cvoid}, Int),
82,401,019✔
333
              dest, destp, src, srcp, n)
334
    elseif isbitstype(T)
2,297,768✔
335
        memmove(destp, srcp, n * aligned_sizeof(T))
80,394,623✔
336
    elseif isbitsunion(T)
5,972✔
337
        memmove(destp, srcp, n * aligned_sizeof(T))
929✔
338
        # copy selector bytes
339
        memmove(
929✔
340
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), dest) + doffs - 1,
341
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), src) + soffs - 1,
342
              n)
343
    else
344
        _unsafe_copyto!(dest, doffs, src, soffs, n)
31,848,074✔
345
    end
346
    @_gc_preserve_end t2
194,644,634✔
347
    @_gc_preserve_end t1
194,644,634✔
348
    return dest
82,429,084✔
349
end
350

351
unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n) =
6,106,987✔
352
    _unsafe_copyto!(dest, doffs, src, soffs, n)
353

354
"""
355
    copyto!(dest, do, src, so, N)
356

357
Copy `N` elements from collection `src` starting at the linear index `so`, to array `dest` starting at
358
the index `do`. Return `dest`.
359
"""
360
function copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
41,112✔
361
    return _copyto_impl!(dest, doffs, src, soffs, n)
12,197,229✔
362
end
363

364
# this is only needed to avoid possible ambiguities with methods added in some packages
365
function copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where T
1,338,251✔
366
    return _copyto_impl!(dest, doffs, src, soffs, n)
413,860,696✔
367
end
368

369
function _copyto_impl!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
1,345,621✔
370
    n == 0 && return dest
230,668,191✔
371
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
195,609,069✔
372
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
195,609,088✔
373
    @boundscheck checkbounds(src, soffs:soffs+n-1)
195,609,049✔
374
    unsafe_copyto!(dest, doffs, src, soffs, n)
195,609,043✔
375
    return dest
195,608,802✔
376
end
377

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

383
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
12,152,234✔
384

385
# also to avoid ambiguities in packages
386
copyto!(dest::Array{T}, src::Array{T}) where {T} = copyto!(dest, 1, src, 1, length(src))
172,421,220✔
387

388
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
389
# for bootstrapping purposes.
390
function fill!(dest::Array{T}, x) where T
152,211✔
391
    xT = x isa T ? x : convert(T, x)::T
152,161✔
392
    for i in eachindex(dest)
1,117,700,635✔
393
        @inbounds dest[i] = xT
2,147,483,647✔
394
    end
2,147,483,647✔
395
    return dest
813,931,533✔
396
end
397

398
"""
399
    copy(x)
400

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

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

409
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
193,671,188✔
410

411
## Constructors ##
412

413
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
106,524✔
414
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
4,174✔
415
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
9,777✔
416
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
9,851✔
417
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
2,065,725✔
418
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
72,729,419✔
419
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
458✔
420

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

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

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

436
julia> getindex(Int8, 1, 2, 3)
437
3-element Vector{Int8}:
438
 1
439
 2
440
 3
441
```
442
"""
443
function getindex(::Type{T}, vals...) where T
715,951✔
444
    @inline
180,210✔
445
    @_effect_free_terminates_locally_meta
180,210✔
446
    a = Vector{T}(undef, length(vals))
870,958,161✔
447
    if vals isa NTuple
180,254✔
448
        @_safeindex for i in 1:length(vals)
129,761✔
449
            a[i] = vals[i]
50,801,444✔
450
        end
244,632✔
451
    else
452
        # use afoldl to avoid type instability inside loop
453
        afoldl(1, vals...) do i, v
58,089✔
454
            @inbounds a[i] = v
122,407✔
455
            return i + 1
122,164✔
456
        end
457
    end
458
    return a
183,490✔
459
end
460

461
function getindex(::Type{Any}, @nospecialize vals...)
26,097,347✔
462
    @_effect_free_terminates_locally_meta
34,704✔
463
    a = Vector{Any}(undef, length(vals))
65,560,456✔
464
    @_safeindex for i = 1:length(vals)
52,035,182✔
465
        a[i] = vals[i]
119,057,177✔
466
    end
132,613,691✔
467
    return a
26,095,944✔
468
end
469
getindex(::Type{Any}) = Vector{Any}()
40,614,291✔
470

471
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
46,286✔
472
    t = @_gc_preserve_begin a
14,107,632✔
473
    p = unsafe_convert(Ptr{Cvoid}, a)
14,107,632✔
474
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
14,107,635✔
475
    @_gc_preserve_end t
14,107,629✔
476
    return a
14,107,629✔
477
end
478

479
to_dim(d::Integer) = d
×
480
to_dim(d::OneTo) = last(d)
326✔
481

482
"""
483
    fill(value, dims::Tuple)
484
    fill(value, dims...)
485

486
Create an array of size `dims` with every location set to `value`.
487

488
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
489
with `1.0` in every location of the array.
490

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

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

504
```jldoctest
505
julia> v = fill([], 3)
506
3-element Vector{Vector{Any}}:
507
 []
508
 []
509
 []
510

511
julia> v[1] === v[2] === v[3]
512
true
513

514
julia> value = v[1]
515
Any[]
516

517
julia> push!(value, 867_5309)
518
1-element Vector{Any}:
519
 8675309
520

521
julia> v
522
3-element Vector{Vector{Any}}:
523
 [8675309]
524
 [8675309]
525
 [8675309]
526
```
527

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

531
```jldoctest
532
julia> v2 = [[] for _ in 1:3]
533
3-element Vector{Vector{Any}}:
534
 []
535
 []
536
 []
537

538
julia> v2[1] === v2[2] === v2[3]
539
false
540

541
julia> push!(v2[1], 8675309)
542
1-element Vector{Any}:
543
 8675309
544

545
julia> v2
546
3-element Vector{Vector{Any}}:
547
 [8675309]
548
 []
549
 []
550
```
551

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

554
# Examples
555
```jldoctest
556
julia> fill(1.0, (2,3))
557
2×3 Matrix{Float64}:
558
 1.0  1.0  1.0
559
 1.0  1.0  1.0
560

561
julia> fill(42)
562
0-dimensional Array{Int64, 0}:
563
42
564

565
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
566
2-element Vector{Vector{Float64}}:
567
 [0.0, 0.0]
568
 [0.0, 0.0]
569

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

572
julia> A # both A[1] and A[2] are the very same vector
573
2-element Vector{Vector{Float64}}:
574
 [42.0, 0.0]
575
 [42.0, 0.0]
576
```
577
"""
578
function fill end
579

580
fill(v, dims::DimOrInd...) = fill(v, dims)
2,147,483,647✔
581
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
582
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
2,147,483,647✔
583
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
393✔
584

585
"""
586
    zeros([T=Float64,] dims::Tuple)
587
    zeros([T=Float64,] dims...)
588

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

592
# Examples
593
```jldoctest
594
julia> zeros(1)
595
1-element Vector{Float64}:
596
 0.0
597

598
julia> zeros(Int8, 2, 3)
599
2×3 Matrix{Int8}:
600
 0  0  0
601
 0  0  0
602
```
603
"""
604
function zeros end
605

606
"""
607
    ones([T=Float64,] dims::Tuple)
608
    ones([T=Float64,] dims...)
609

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

613
# Examples
614
```jldoctest
615
julia> ones(1,2)
616
1×2 Matrix{Float64}:
617
 1.0  1.0
618

619
julia> ones(ComplexF64, 2, 3)
620
2×3 Matrix{ComplexF64}:
621
 1.0+0.0im  1.0+0.0im  1.0+0.0im
622
 1.0+0.0im  1.0+0.0im  1.0+0.0im
623
```
624
"""
625
function ones end
626

627
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
628
    @eval begin
629
        $fname(dims::DimOrInd...) = $fname(dims)
20,447,256✔
630
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
914,343,193✔
631
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,488,828✔
632
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
885✔
633
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
71,606✔
634
            a = Array{T,N}(undef, dims)
103,837,784✔
635
            fill!(a, $felt(T))
1,341,159,009✔
636
            return a
103,837,784✔
637
        end
638
        function $fname(::Type{T}, dims::Tuple{}) where {T}
20✔
639
            a = Array{T}(undef)
20✔
640
            fill!(a, $felt(T))
20✔
641
            return a
20✔
642
        end
643
    end
644
end
645

646
function _one(unit::T, x::AbstractMatrix) where T
158✔
647
    require_one_based_indexing(x)
158✔
648
    m,n = size(x)
158✔
649
    m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
158✔
650
    # Matrix{T}(I, m, m)
651
    I = zeros(T, m, m)
3,765✔
652
    for i in 1:m
316✔
653
        I[i,i] = unit
649✔
654
    end
1,140✔
655
    I
158✔
656
end
657

658
one(x::AbstractMatrix{T}) where {T} = _one(one(T), x)
131✔
659
oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)
29✔
660

661
## Conversions ##
662

663
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
192,243✔
664

665
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
76✔
666

667
## Constructors ##
668

669
if nameof(@__MODULE__) === :Base  # avoid method overwrite
670
# constructors should make copies
671
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
193,402✔
672
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
10,199✔
673
end
674

675
## copying iterators to containers
676

677
"""
678
    collect(element_type, collection)
679

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

683
# Examples
684
```jldoctest
685
julia> collect(Float64, 1:2:5)
686
3-element Vector{Float64}:
687
 1.0
688
 3.0
689
 5.0
690
```
691
"""
692
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
33,829,793✔
693

694
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
12,135,982✔
695
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
696
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
21,693,810✔
697
    a = Vector{T}()
21,693,810✔
698
    for x in itr
37,320,008✔
699
        push!(a, x)
80,355,234✔
700
    end
145,084,271✔
701
    return a
21,693,810✔
702
end
703

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

707
_similar_shape(itr, ::SizeUnknown) = nothing
1✔
708
_similar_shape(itr, ::HasLength) = length(itr)::Integer
37,461,782✔
709
_similar_shape(itr, ::HasShape) = axes(itr)
530,393,856✔
710

711
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
908,028✔
712
    similar(c, T, 0)
713
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
4,703,530✔
714
    similar(c, T, len)
715
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
132,647✔
716
    similar(c, T, axs)
717

718
# make a collection appropriate for collecting `itr::Generator`
719
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
310✔
720
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
28,622,760✔
721
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
530,460,870✔
722

723
# used by syntax lowering for simple typed comprehensions
724
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
556,175,715✔
725

726

727
"""
728
    collect(collection)
729

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

735
Used by comprehensions to turn a generator into an `Array`.
736

737
# Examples
738
```jldoctest
739
julia> collect(1:2:13)
740
7-element Vector{Int64}:
741
  1
742
  3
743
  5
744
  7
745
  9
746
 11
747
 13
748

749
julia> [x^2 for x in 1:8 if isodd(x)]
750
4-element Vector{Int64}:
751
  1
752
  9
753
 25
754
 49
755
```
756
"""
757
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
6,081,990✔
758

759
collect(A::AbstractArray) = _collect_indices(axes(A), A)
132,161✔
760

761
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
132,038✔
762

763
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
5,174,201✔
764
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
765

766
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
907,994✔
767
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
907,994✔
768
    for x in itr
1,814,966✔
769
        push!(a,x)
8,633,966✔
770
    end
14,752,859✔
771
    return a
907,993✔
772
end
773

774
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
775
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
177,951✔
776
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
777
function _collect_indices(indsA, A)
121✔
778
    B = Array{eltype(A)}(undef, length.(indsA))
121✔
779
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
780
end
781

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

796
# define this as a macro so that the call to Core.Compiler
797
# gets inlined into the caller before recursion detection
798
# gets a chance to see it, so that recursive calls to the caller
799
# don't trigger the inference limiter
800
if isdefined(Core, :Compiler)
801
    macro default_eltype(itr)
1✔
802
        I = esc(itr)
1✔
803
        return quote
1✔
804
            if $I isa Generator && ($I).f isa Type
202,221✔
805
                T = ($I).f
13,240✔
806
            else
807
                T = Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)})
188,981✔
808
            end
809
            promote_typejoin_union(T)
202,273✔
810
        end
811
    end
812
else
813
    macro default_eltype(itr)
814
        I = esc(itr)
815
        return quote
816
            if $I isa Generator && ($I).f isa Type
817
                promote_typejoin_union($I.f)
818
            else
819
                Any
820
            end
821
        end
822
    end
823
end
824

825
function collect(itr::Generator)
591,786✔
826
    isz = IteratorSize(itr.iter)
71,719✔
827
    et = @default_eltype(itr)
×
828
    if isa(isz, SizeUnknown)
71,719✔
829
        return grow_to!(Vector{et}(), itr)
90,140✔
830
    else
831
        shp = _similar_shape(itr, isz)
502,006✔
832
        y = iterate(itr)
986,325✔
833
        if y === nothing
501,752✔
834
            return _array_for(et, isz, shp)
6,858✔
835
        end
836
        v1, st = y
70,223✔
837
        dest = _array_for(typeof(v1), isz, shp)
494,952✔
838
        # The typeassert gives inference a helping hand on the element type and dimensionality
839
        # (work-around for #28382)
840
        et′ = et <: Type ? Type : et
70,223✔
841
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
70,270✔
842
        collect_to_with_first!(dest, v1, itr, st)::RT
10,488,899✔
843
    end
844
end
845

846
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
34✔
847
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
848

849
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
131,499✔
850
    et = @default_eltype(itr)
116,315✔
851
    shp = _similar_shape(itr, isz)
131,500✔
852
    y = iterate(itr)
260,790✔
853
    if y === nothing
131,497✔
854
        return _similar_for(c, et, itr, isz, shp)
1,815✔
855
    end
856
    v1, st = y
115,264✔
857
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
129,699✔
858
    # The typeassert gives inference a helping hand on the element type and dimensionality
859
    # (work-around for #28382)
860
    et′ = et <: Type ? Type : et
115,212✔
861
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
115,227✔
862
    collect_to_with_first!(dest, v1, itr, st)::RT
130,249✔
863
end
864

865
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
185,634✔
866
    i1 = first(LinearIndices(dest))
185,435✔
867
    dest[i1] = v1
624,576✔
868
    return collect_to!(dest, itr, i1+1, st)
85,942,186✔
869
end
870

871
function collect_to_with_first!(dest, v1, itr, st)
×
872
    push!(dest, v1)
×
873
    return grow_to!(dest, itr, st)
×
874
end
875

876
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
376✔
877
    @inline
376✔
878
    new = similar(dest, promote_typejoin(T, typeof(el)))
380✔
879
    f = first(LinearIndices(dest))
376✔
880
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
747✔
881
    @inbounds new[i] = el
376✔
882
    return new
376✔
883
end
884

885
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
226,291✔
886
    # collect to dest array, checking the type of each result. if a result does not
887
    # match, widen the result type and re-dispatch.
888
    i = offs
185,811✔
889
    while true
93,920,261✔
890
        y = iterate(itr, st)
187,214,464✔
891
        y === nothing && break
93,920,252✔
892
        el, st = y
91,926,476✔
893
        if el isa T
91,924,996✔
894
            @inbounds dest[i] = el
93,295,700✔
895
            i += 1
93,295,309✔
896
        else
897
            new = setindex_widen_up_to(dest, el, i)
460✔
898
            return collect_to!(new, itr, i+1, st)
376✔
899
        end
900
    end
93,295,309✔
901
    return dest
624,567✔
902
end
903

904
function grow_to!(dest, itr)
1,210✔
905
    y = iterate(itr)
1,500✔
906
    y === nothing && return dest
1,210✔
907
    dest2 = empty(dest, typeof(y[1]))
311✔
908
    push!(dest2, y[1])
332✔
909
    grow_to!(dest2, itr, y[2])
295✔
910
end
911

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

925
function grow_to!(dest, itr, st)
348✔
926
    T = eltype(dest)
243✔
927
    y = iterate(itr, st)
638✔
928
    while y !== nothing
4,214✔
929
        el, st = y
2,593✔
930
        if el isa T
2,593✔
931
            push!(dest, el)
3,869✔
932
        else
933
            new = push_widen(dest, el)
55✔
934
            return grow_to!(new, itr, st)
53✔
935
        end
936
        y = iterate(itr, st)
6,068✔
937
    end
3,866✔
938
    return dest
295✔
939
end
940

941
## Iteration ##
942

943
iterate(A::Array, i=1) = (@inline; (i % UInt) - 1 < length(A) ? (@inbounds A[i], i + 1) : nothing)
2,147,483,647✔
944

945
## Indexing: getindex ##
946

947
"""
948
    getindex(collection, key...)
949

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

953
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
954

955
# Examples
956
```jldoctest
957
julia> A = Dict("a" => 1, "b" => 2)
958
Dict{String, Int64} with 2 entries:
959
  "b" => 2
960
  "a" => 1
961

962
julia> getindex(A, "a")
963
1
964
```
965
"""
966
function getindex end
967

968
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
969
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
1,843,681✔
970
    @inline
866,167✔
971
    @boundscheck checkbounds(A, I)
72,390,149✔
972
    lI = length(I)
72,390,158✔
973
    X = similar(A, axes(I))
72,390,159✔
974
    if lI > 0
72,390,147✔
975
        copyto!(X, firstindex(X), A, first(I), lI)
131,591,506✔
976
    end
977
    return X
72,390,147✔
978
end
979

980
# getindex for carrying out logical indexing for AbstractUnitRange{Bool} as Bool <: Integer
981
getindex(a::Array, r::AbstractUnitRange{Bool}) = getindex(a, to_index(r))
27✔
982

983
function getindex(A::Array, c::Colon)
4,908✔
984
    lI = length(A)
2,059,957✔
985
    X = similar(A, lI)
2,059,957✔
986
    if lI > 0
2,059,957✔
987
        unsafe_copyto!(X, 1, A, 1, lI)
2,059,955✔
988
    end
989
    return X
2,059,957✔
990
end
991

992
# This is redundant with the abstract fallbacks, but needed for bootstrap
993
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
3,166,456✔
994
    return S[ A[i] for i in I ]
13,046,056✔
995
end
996

997
## Indexing: setindex! ##
998

999
"""
1000
    setindex!(collection, value, key...)
1001

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

1005
# Examples
1006
```jldoctest
1007
julia> a = Dict("a"=>1)
1008
Dict{String, Int64} with 1 entry:
1009
  "a" => 1
1010

1011
julia> setindex!(a, 2, "b")
1012
Dict{String, Int64} with 2 entries:
1013
  "b" => 2
1014
  "a" => 1
1015
```
1016
"""
1017
function setindex! end
1018

1019
@eval setindex!(A::Array{T}, x, i1::Int) where {T} =
2,147,483,647✔
1020
    arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1)
1021
@eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
62,522,729✔
1022
    (@inline; arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1, i2, I...))
62,525,257✔
1023

1024
__inbounds_setindex!(A::Array{T}, x, i1::Int) where {T} =
2,147,483,647✔
1025
    arrayset(false, A, convert(T,x)::T, i1)
1026
__inbounds_setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
×
1027
    (@inline; arrayset(false, A, convert(T,x)::T, i1, i2, I...))
×
1028

1029
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1030
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
813,180✔
1031
    @_propagate_inbounds_meta
813,178✔
1032
    @boundscheck setindex_shape_check(X, length(I))
7,359,837✔
1033
    require_one_based_indexing(X)
813,178✔
1034
    X′ = unalias(A, X)
818,538✔
1035
    I′ = unalias(A, I)
813,610✔
1036
    count = 1
813,178✔
1037
    for i in I′
13,766,988✔
1038
        @inbounds x = X′[count]
18,468,649✔
1039
        A[i] = x
18,470,733✔
1040
        count += 1
18,468,649✔
1041
    end
30,482,605✔
1042
    return A
7,359,837✔
1043
end
1044

1045
# Faster contiguous setindex! with copyto!
1046
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
1,008,751✔
1047
    @inline
1,007,986✔
1048
    @boundscheck checkbounds(A, I)
1,009,265✔
1049
    lI = length(I)
1,009,265✔
1050
    @boundscheck setindex_shape_check(X, lI)
1,009,265✔
1051
    if lI > 0
1,009,265✔
1052
        unsafe_copyto!(A, first(I), X, 1, lI)
1,009,161✔
1053
    end
1054
    return A
1,009,265✔
1055
end
1056
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
47✔
1057
    @inline
47✔
1058
    lI = length(A)
47✔
1059
    @boundscheck setindex_shape_check(X, lI)
47✔
1060
    if lI > 0
47✔
1061
        unsafe_copyto!(A, 1, X, 1, lI)
47✔
1062
    end
1063
    return A
47✔
1064
end
1065

1066
# efficiently grow an array
1067

1068
_growbeg!(a::Vector, delta::Integer) =
5,303,693✔
1069
    ccall(:jl_array_grow_beg, Cvoid, (Any, UInt), a, delta)
1070
_growend!(a::Vector, delta::Integer) =
2,147,483,647✔
1071
    ccall(:jl_array_grow_end, Cvoid, (Any, UInt), a, delta)
1072
_growat!(a::Vector, i::Integer, delta::Integer) =
83,872,783✔
1073
    ccall(:jl_array_grow_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1074

1075
# efficiently delete part of an array
1076

1077
_deletebeg!(a::Vector, delta::Integer) =
28,657,852✔
1078
    ccall(:jl_array_del_beg, Cvoid, (Any, UInt), a, delta)
1079
_deleteend!(a::Vector, delta::Integer) =
1,032,257,448✔
1080
    ccall(:jl_array_del_end, Cvoid, (Any, UInt), a, delta)
1081
_deleteat!(a::Vector, i::Integer, delta::Integer) =
5,467,927✔
1082
    ccall(:jl_array_del_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1083

1084
## Dequeue functionality ##
1085

1086
"""
1087
    push!(collection, items...) -> collection
1088

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

1092
# Examples
1093
```jldoctest
1094
julia> push!([1, 2, 3], 4, 5, 6)
1095
6-element Vector{Int64}:
1096
 1
1097
 2
1098
 3
1099
 4
1100
 5
1101
 6
1102
```
1103

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

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

1110
See also [`pushfirst!`](@ref).
1111
"""
1112
function push! end
1113

1114
function push!(a::Vector{T}, item) where T
339,173✔
1115
    # convert first so we don't grow the array if the assignment won't work
1116
    itemT = item isa T ? item : convert(T, item)::T
34,017,268✔
1117
    _growend!(a, 1)
1,819,083,733✔
1118
    @_safeindex a[length(a)] = itemT
1,819,083,733✔
1119
    return a
15,738,997✔
1120
end
1121

1122
# specialize and optimize the single argument case
1123
function push!(a::Vector{Any}, @nospecialize x)
3,199,682✔
1124
    _growend!(a, 1)
123,893,378✔
1125
    @_safeindex a[length(a)] = x
123,893,371✔
1126
    return a
2,920,662✔
1127
end
1128
function push!(a::Vector{Any}, @nospecialize x...)
1,024,072✔
1129
    @_terminates_locally_meta
17✔
1130
    na = length(a)
1,024,072✔
1131
    nx = length(x)
17✔
1132
    _growend!(a, nx)
1,024,072✔
1133
    @_safeindex for i = 1:nx
2,048,142✔
1134
        a[na+i] = x[i]
2,964,542✔
1135
    end
3,072,330✔
1136
    return a
1,024,072✔
1137
end
1138

1139
"""
1140
    append!(collection, collections...) -> collection.
1141

1142
For an ordered container `collection`, add the elements of each `collections`
1143
to the end of it.
1144

1145
!!! compat "Julia 1.6"
1146
    Specifying multiple collections to be appended requires at least Julia 1.6.
1147

1148
# Examples
1149
```jldoctest
1150
julia> append!([1], [2, 3])
1151
3-element Vector{Int64}:
1152
 1
1153
 2
1154
 3
1155

1156
julia> append!([1, 2, 3], [4, 5], [6])
1157
6-element Vector{Int64}:
1158
 1
1159
 2
1160
 3
1161
 4
1162
 5
1163
 6
1164
```
1165

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

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

1172
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1173
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1174
"""
1175
function append! end
1176

1177
function append!(a::Vector, items::AbstractVector)
71,976,405✔
1178
    itemindices = eachindex(items)
71,987,317✔
1179
    n = length(itemindices)
49,812✔
1180
    _growend!(a, n)
71,987,317✔
1181
    copyto!(a, length(a)-n+1, items, first(itemindices), n)
108,926,824✔
1182
    return a
71,987,317✔
1183
end
1184

1185
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
67,786,651✔
1186
push!(a::AbstractVector, iter...) = append!(a, iter)
740,284✔
1187

1188
append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
79✔
1189

1190
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
21,614,248✔
1191
    @_terminates_locally_meta
740,293✔
1192
    n = length(a)
21,614,248✔
1193
    i = lastindex(a)
21,614,248✔
1194
    resize!(a, n+Int(length(iter))::Int)
34,490,517✔
1195
    for (i, item) in zip(i+1:lastindex(a), iter)
30,352,227✔
1196
        if isa(a, Vector) # give better effects for builtin vectors
1,485,283✔
1197
            @_safeindex a[i] = item
40,577,980✔
1198
        else
1199
            a[i] = item
×
1200
        end
1201
    end
72,414,337✔
1202
    a
21,614,248✔
1203
end
1204
function _append!(a::AbstractVector, ::IteratorSize, iter)
46,172,402✔
1205
    for item in iter
46,172,404✔
1206
        push!(a, item)
48,133,034✔
1207
    end
48,133,039✔
1208
    a
46,172,402✔
1209
end
1210

1211
"""
1212
    prepend!(a::Vector, collections...) -> collection
1213

1214
Insert the elements of each `collections` to the beginning of `a`.
1215

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

1219
!!! compat "Julia 1.6"
1220
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1221

1222
# Examples
1223
```jldoctest
1224
julia> prepend!([3], [1, 2])
1225
3-element Vector{Int64}:
1226
 1
1227
 2
1228
 3
1229

1230
julia> prepend!([6], [1, 2], [3, 4, 5])
1231
6-element Vector{Int64}:
1232
 1
1233
 2
1234
 3
1235
 4
1236
 5
1237
 6
1238
```
1239
"""
1240
function prepend! end
1241

1242
function prepend!(a::Vector, items::AbstractVector)
5,278✔
1243
    itemindices = eachindex(items)
5,278✔
1244
    n = length(itemindices)
5,232✔
1245
    _growbeg!(a, n)
5,278✔
1246
    if a === items
5,278✔
1247
        copyto!(a, 1, items, n+1, n)
2✔
1248
    else
1249
        copyto!(a, 1, items, first(itemindices), n)
5,973✔
1250
    end
1251
    return a
5,278✔
1252
end
1253

1254
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
13✔
1255
pushfirst!(a::Vector, iter...) = prepend!(a, iter)
7✔
1256

1257
prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
4✔
1258

1259
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
7✔
1260
    @_terminates_locally_meta
7✔
1261
    require_one_based_indexing(a)
7✔
1262
    n = length(iter)
7✔
1263
    _growbeg!(a, n)
7✔
1264
    i = 0
7✔
1265
    for item in iter
7✔
1266
        @_safeindex a[i += 1] = item
13✔
1267
    end
18✔
1268
    a
7✔
1269
end
1270
function _prepend!(a::Vector, ::IteratorSize, iter)
2✔
1271
    n = 0
2✔
1272
    for item in iter
3✔
1273
        n += 1
5✔
1274
        pushfirst!(a, item)
5✔
1275
    end
9✔
1276
    reverse!(a, 1, n)
2✔
1277
    a
2✔
1278
end
1279

1280
"""
1281
    resize!(a::Vector, n::Integer) -> Vector
1282

1283
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1284
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1285
guaranteed to be initialized.
1286

1287
# Examples
1288
```jldoctest
1289
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1290
3-element Vector{Int64}:
1291
 6
1292
 5
1293
 4
1294

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

1297
julia> length(a)
1298
8
1299

1300
julia> a[1:6]
1301
6-element Vector{Int64}:
1302
 6
1303
 5
1304
 4
1305
 3
1306
 2
1307
 1
1308
```
1309
"""
1310
function resize!(a::Vector, nl::Integer)
7,675,790✔
1311
    l = length(a)
1,269,217,182✔
1312
    if nl > l
1,269,217,182✔
1313
        _growend!(a, nl-l)
630,396,700✔
1314
    elseif nl != l
638,820,484✔
1315
        if nl < 0
80,743,534✔
1316
            _throw_argerror("new length must be ≥ 0")
2✔
1317
        end
1318
        _deleteend!(a, l-nl)
312,932,829✔
1319
    end
1320
    return a
1,269,217,180✔
1321
end
1322

1323
"""
1324
    sizehint!(s, n) -> s
1325

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

1331
See also [`resize!`](@ref).
1332

1333
# Notes on the performance model
1334

1335
For types that support `sizehint!`,
1336

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

1341
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1342
   `Base`.
1343

1344
3. `empty!` is nearly costless (and O(1)) for types that support this kind of preallocation.
1345
"""
1346
function sizehint! end
1347

1348
function sizehint!(a::Vector, sz::Integer)
642,467✔
1349
    ccall(:jl_array_sizehint, Cvoid, (Any, UInt), a, sz)
726,784✔
1350
    a
707,245✔
1351
end
1352

1353
# Fall-back implementation for non-shrinkable collections
1354
_sizehint!(a, sz; shrink) = sizehint!(a, sz)
4,008,362✔
1355

1356
"""
1357
    pop!(collection) -> item
1358

1359
Remove an item in `collection` and return it. If `collection` is an
1360
ordered container, the last item is returned; for unordered containers,
1361
an arbitrary element is returned.
1362

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

1365
# Examples
1366
```jldoctest
1367
julia> A=[1, 2, 3]
1368
3-element Vector{Int64}:
1369
 1
1370
 2
1371
 3
1372

1373
julia> pop!(A)
1374
3
1375

1376
julia> A
1377
2-element Vector{Int64}:
1378
 1
1379
 2
1380

1381
julia> S = Set([1, 2])
1382
Set{Int64} with 2 elements:
1383
  2
1384
  1
1385

1386
julia> pop!(S)
1387
2
1388

1389
julia> S
1390
Set{Int64} with 1 element:
1391
  1
1392

1393
julia> pop!(Dict(1=>2))
1394
1 => 2
1395
```
1396
"""
1397
function pop!(a::Vector)
73,400✔
1398
    if isempty(a)
633,905,193✔
1399
        _throw_argerror("array must be non-empty")
1✔
1400
    end
1401
    item = a[end]
633,905,192✔
1402
    _deleteend!(a, 1)
633,905,192✔
1403
    return item
633,905,192✔
1404
end
1405

1406
"""
1407
    popat!(a::Vector, i::Integer, [default])
1408

1409
Remove the item at the given `i` and return it. Subsequent items
1410
are shifted to fill the resulting gap.
1411
When `i` is not a valid index for `a`, return `default`, or throw an error if
1412
`default` is not specified.
1413

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

1416
!!! compat "Julia 1.5"
1417
    This function is available as of Julia 1.5.
1418

1419
# Examples
1420
```jldoctest
1421
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1422
3
1423

1424
julia> a
1425
3-element Vector{Int64}:
1426
 4
1427
 2
1428
 1
1429

1430
julia> popat!(a, 4, missing)
1431
missing
1432

1433
julia> popat!(a, 4)
1434
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1435
[...]
1436
```
1437
"""
1438
function popat!(a::Vector, i::Integer)
7✔
1439
    x = a[i]
7✔
1440
    _deleteat!(a, i, 1)
4✔
1441
    x
4✔
1442
end
1443

1444
function popat!(a::Vector, i::Integer, default)
2✔
1445
    if 1 <= i <= length(a)
2✔
1446
        x = @inbounds a[i]
1✔
1447
        _deleteat!(a, i, 1)
1✔
1448
        x
1✔
1449
    else
1450
        default
1✔
1451
    end
1452
end
1453

1454
"""
1455
    pushfirst!(collection, items...) -> collection
1456

1457
Insert one or more `items` at the beginning of `collection`.
1458

1459
This function is called `unshift` in many other programming languages.
1460

1461
# Examples
1462
```jldoctest
1463
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1464
6-element Vector{Int64}:
1465
 5
1466
 6
1467
 1
1468
 2
1469
 3
1470
 4
1471
```
1472
"""
1473
function pushfirst!(a::Vector{T}, item) where T
76,969✔
1474
    item = item isa T ? item : convert(T, item)::T
76,952✔
1475
    _growbeg!(a, 1)
4,110,168✔
1476
    @_safeindex a[1] = item
4,110,168✔
1477
    return a
76,969✔
1478
end
1479

1480
# specialize and optimize the single argument case
1481
function pushfirst!(a::Vector{Any}, @nospecialize x)
126✔
1482
    _growbeg!(a, 1)
819,261✔
1483
    @_safeindex a[1] = x
819,261✔
1484
    return a
124✔
1485
end
1486
function pushfirst!(a::Vector{Any}, @nospecialize x...)
748✔
1487
    @_terminates_locally_meta
2✔
1488
    na = length(a)
2✔
1489
    nx = length(x)
2✔
1490
    _growbeg!(a, nx)
748✔
1491
    @_safeindex for i = 1:nx
1,494✔
1492
        a[i] = x[i]
1,498✔
1493
    end
2,248✔
1494
    return a
748✔
1495
end
1496

1497
"""
1498
    popfirst!(collection) -> item
1499

1500
Remove the first `item` from `collection`.
1501

1502
This function is called `shift` in many other programming languages.
1503

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

1506
# Examples
1507
```jldoctest
1508
julia> A = [1, 2, 3, 4, 5, 6]
1509
6-element Vector{Int64}:
1510
 1
1511
 2
1512
 3
1513
 4
1514
 5
1515
 6
1516

1517
julia> popfirst!(A)
1518
1
1519

1520
julia> A
1521
5-element Vector{Int64}:
1522
 2
1523
 3
1524
 4
1525
 5
1526
 6
1527
```
1528
"""
1529
function popfirst!(a::Vector)
1,038,034✔
1530
    if isempty(a)
28,599,651✔
1531
        _throw_argerror("array must be non-empty")
1✔
1532
    end
1533
    item = a[1]
28,599,650✔
1534
    _deletebeg!(a, 1)
28,599,650✔
1535
    return item
28,599,648✔
1536
end
1537

1538
"""
1539
    insert!(a::Vector, index::Integer, item)
1540

1541
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1542
the resulting `a`.
1543

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

1546
# Examples
1547
```jldoctest
1548
julia> insert!(Any[1:6;], 3, "here")
1549
7-element Vector{Any}:
1550
 1
1551
 2
1552
  "here"
1553
 3
1554
 4
1555
 5
1556
 6
1557
```
1558
"""
1559
function insert!(a::Array{T,1}, i::Integer, item) where T
211,046✔
1560
    # Throw convert error before changing the shape of the array
1561
    _item = item isa T ? item : convert(T, item)::T
211,049✔
1562
    _growat!(a, i, 1)
83,847,241✔
1563
    # _growat! already did bound check
1564
    @inbounds a[i] = _item
83,847,235✔
1565
    return a
211,040✔
1566
end
1567

1568
"""
1569
    deleteat!(a::Vector, i::Integer)
1570

1571
Remove the item at the given `i` and return the modified `a`. Subsequent items
1572
are shifted to fill the resulting gap.
1573

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

1576
# Examples
1577
```jldoctest
1578
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1579
5-element Vector{Int64}:
1580
 6
1581
 4
1582
 3
1583
 2
1584
 1
1585
```
1586
"""
1587
function deleteat!(a::Vector, i::Integer)
16,729✔
1588
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,729✔
1589
    _deleteat!(a, i, 1)
5,371,484✔
1590
    return a
16,723✔
1591
end
1592

1593
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
75,587✔
1594
    if eltype(r) === Bool
75,587✔
1595
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1596
    else
1597
        n = length(a)
75,581✔
1598
        f = first(r)
75,680✔
1599
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
75,581✔
1600
        isempty(r) || _deleteat!(a, f, length(r))
169,884✔
1601
        return a
86,767✔
1602
    end
1603
end
1604

1605
"""
1606
    deleteat!(a::Vector, inds)
1607

1608
Remove the items at the indices given by `inds`, and return the modified `a`.
1609
Subsequent items are shifted to fill the resulting gap.
1610

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

1614
# Examples
1615
```jldoctest
1616
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1617
3-element Vector{Int64}:
1618
 5
1619
 3
1620
 1
1621

1622
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1623
3-element Vector{Int64}:
1624
 5
1625
 3
1626
 1
1627

1628
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1629
ERROR: ArgumentError: indices must be unique and sorted
1630
Stacktrace:
1631
[...]
1632
```
1633
"""
1634
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1635
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
94,370✔
1636

1637
struct Nowhere; end
1638
push!(::Nowhere, _) = nothing
1,490,851✔
1639
_growend!(::Nowhere, _) = nothing
×
1640

1641
@inline function _push_deleted!(dltd, a::Vector, ind)
1,490,853✔
1642
    if @inbounds isassigned(a, ind)
1,556,447✔
1643
        push!(dltd, @inbounds a[ind])
1,556,458✔
1644
    else
1645
        _growend!(dltd, 1)
1✔
1646
    end
1647
end
1648

1649
@inline function _copy_item!(a::Vector, p, q)
4,377,348✔
1650
    if @inbounds isassigned(a, q)
4,409,185✔
1651
        @inbounds a[p] = a[q]
4,409,203✔
1652
    else
1653
        _unsetindex!(a, p)
1✔
1654
    end
1655
end
1656

1657
function _deleteat!(a::Vector, inds, dltd=Nowhere())
130,091✔
1658
    n = length(a)
188,779✔
1659
    y = iterate(inds)
94,634✔
1660
    y === nothing && return a
94,390✔
1661
    (p, s) = y
35,464✔
1662
    checkbounds(a, p)
94,158✔
1663
    _push_deleted!(dltd, a, p)
94,151✔
1664
    q = p+1
94,146✔
1665
    while true
1,556,447✔
1666
        y = iterate(inds, s)
1,650,587✔
1667
        y === nothing && break
1,556,447✔
1668
        (i,s) = y
1,455,395✔
1669
        if !(q <= i <= n)
1,462,303✔
1670
            if i < q
2✔
1671
                _throw_argerror("indices must be unique and sorted")
1✔
1672
            else
1673
                throw(BoundsError())
1✔
1674
            end
1675
        end
1676
        while q < i
2,888,450✔
1677
            _copy_item!(a, p, q)
1,426,161✔
1678
            p += 1; q += 1
2,852,298✔
1679
        end
1,426,149✔
1680
        _push_deleted!(dltd, a, i)
1,462,309✔
1681
        q = i+1
1,462,301✔
1682
    end
1,462,301✔
1683
    while q <= n
3,034,986✔
1684
        _copy_item!(a, p, q)
2,940,850✔
1685
        p += 1; q += 1
5,881,684✔
1686
    end
2,940,842✔
1687
    _deleteend!(a, n-p+1)
94,144✔
1688
    return a
94,144✔
1689
end
1690

1691
# Simpler and more efficient version for logical indexing
1692
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1693
    n = length(a)
4,029✔
1694
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1695
    p = 1
4,024✔
1696
    for (q, i) in enumerate(inds)
8,047✔
1697
        _copy_item!(a, p, q)
42,194✔
1698
        p += !i
42,194✔
1699
    end
80,365✔
1700
    _deleteend!(a, n-p+1)
4,024✔
1701
    return a
4,024✔
1702
end
1703

1704
const _default_splice = []
1705

1706
"""
1707
    splice!(a::Vector, index::Integer, [replacement]) -> item
1708

1709
Remove the item at the given index, and return the removed item.
1710
Subsequent items are shifted left to fill the resulting gap.
1711
If specified, replacement values from an ordered
1712
collection will be spliced in place of the removed item.
1713

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

1716
# Examples
1717
```jldoctest
1718
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1719
2
1720

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

1729
julia> splice!(A, 5, -1)
1730
1
1731

1732
julia> A
1733
5-element Vector{Int64}:
1734
  6
1735
  5
1736
  4
1737
  3
1738
 -1
1739

1740
julia> splice!(A, 1, [-1, -2, -3])
1741
6
1742

1743
julia> A
1744
7-element Vector{Int64}:
1745
 -1
1746
 -2
1747
 -3
1748
  5
1749
  4
1750
  3
1751
 -1
1752
```
1753

1754
To insert `replacement` before an index `n` without removing any items, use
1755
`splice!(collection, n:n-1, replacement)`.
1756
"""
1757
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,709✔
1758
    v = a[i]
3,722✔
1759
    m = length(ins)
3,431✔
1760
    if m == 0
3,431✔
1761
        _deleteat!(a, i, 1)
556✔
1762
    elseif m == 1
2,875✔
1763
        a[i] = only(ins)
265✔
1764
    else
1765
        _growat!(a, i, m-1)
2,610✔
1766
        k = 1
2,610✔
1767
        for x in ins
2,610✔
1768
            a[i+k-1] = x
331,264✔
1769
            k += 1
331,264✔
1770
        end
331,264✔
1771
    end
1772
    return v
3,431✔
1773
end
1774

1775
"""
1776
    splice!(a::Vector, indices, [replacement]) -> items
1777

1778
Remove items at specified indices, and return a collection containing
1779
the removed items.
1780
Subsequent items are shifted left to fill the resulting gaps.
1781
If specified, replacement values from an ordered collection will be spliced in
1782
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
1783

1784
To insert `replacement` before an index `n` without removing any items, use
1785
`splice!(collection, n:n-1, replacement)`.
1786

1787
!!! compat "Julia 1.5"
1788
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1789

1790
!!! compat "Julia 1.8"
1791
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1792

1793
# Examples
1794
```jldoctest
1795
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
1796
Int64[]
1797

1798
julia> A
1799
8-element Vector{Int64}:
1800
 -1
1801
 -2
1802
 -3
1803
  2
1804
  5
1805
  4
1806
  3
1807
 -1
1808
```
1809
"""
1810
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
105,771✔
1811
    v = a[r]
176,141✔
1812
    m = length(ins)
71,833✔
1813
    if m == 0
71,833✔
1814
        deleteat!(a, r)
74,257✔
1815
        return v
37,189✔
1816
    end
1817

1818
    n = length(a)
34,644✔
1819
    f = first(r)
34,644✔
1820
    l = last(r)
34,644✔
1821
    d = length(r)
34,644✔
1822

1823
    if m < d
34,644✔
1824
        delta = d - m
12,692✔
1825
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
19,126✔
1826
    elseif m > d
21,952✔
1827
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
21,830✔
1828
    end
1829

1830
    k = 1
34,560✔
1831
    for x in ins
46,150✔
1832
        a[f+k-1] = x
5,378,479✔
1833
        k += 1
4,034,162✔
1834
    end
5,401,807✔
1835
    return v
34,644✔
1836
end
1837

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

1840
function empty!(a::Vector)
120,911✔
1841
    _deleteend!(a, length(a))
85,194,456✔
1842
    return a
85,194,456✔
1843
end
1844

1845
# use memcmp for cmp on byte arrays
1846
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
1847
    ta = @_gc_preserve_begin a
3✔
1848
    tb = @_gc_preserve_begin b
3✔
1849
    pa = unsafe_convert(Ptr{Cvoid}, a)
3✔
1850
    pb = unsafe_convert(Ptr{Cvoid}, b)
3✔
1851
    c = memcmp(pa, pb, min(length(a),length(b)))
3✔
1852
    @_gc_preserve_end ta
3✔
1853
    @_gc_preserve_end tb
3✔
1854
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
1855
end
1856

1857
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
1858
# use memcmp for == on bit integer types
1859
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,731✔
1860
    if size(a) == size(b)
3,402✔
1861
        ta = @_gc_preserve_begin a
1,731✔
1862
        tb = @_gc_preserve_begin b
1,731✔
1863
        pa = unsafe_convert(Ptr{Cvoid}, a)
1,731✔
1864
        pb = unsafe_convert(Ptr{Cvoid}, b)
1,731✔
1865
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
1,731✔
1866
        @_gc_preserve_end ta
1,731✔
1867
        @_gc_preserve_end tb
1,731✔
1868
        return c == 0
1,731✔
1869
    else
1870
        return false
×
1871
    end
1872
end
1873

1874
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
13,370✔
1875
    len = length(a)
47,684✔
1876
    if len == length(b)
47,684✔
1877
        ta = @_gc_preserve_begin a
47,560✔
1878
        tb = @_gc_preserve_begin b
47,560✔
1879
        T = eltype(Arr)
13,246✔
1880
        pa = unsafe_convert(Ptr{T}, a)
47,560✔
1881
        pb = unsafe_convert(Ptr{T}, b)
47,560✔
1882
        c = memcmp(pa, pb, sizeof(T) * len)
47,560✔
1883
        @_gc_preserve_end ta
47,560✔
1884
        @_gc_preserve_end tb
47,560✔
1885
        return c == 0
47,560✔
1886
    else
1887
        return false
124✔
1888
    end
1889
end
1890

1891
"""
1892
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
1893

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

1897
# Examples
1898
```jldoctest
1899
julia> A = Vector(1:5)
1900
5-element Vector{Int64}:
1901
 1
1902
 2
1903
 3
1904
 4
1905
 5
1906

1907
julia> reverse(A)
1908
5-element Vector{Int64}:
1909
 5
1910
 4
1911
 3
1912
 2
1913
 1
1914

1915
julia> reverse(A, 1, 4)
1916
5-element Vector{Int64}:
1917
 4
1918
 3
1919
 2
1920
 1
1921
 5
1922

1923
julia> reverse(A, 3, 5)
1924
5-element Vector{Int64}:
1925
 1
1926
 2
1927
 5
1928
 4
1929
 3
1930
```
1931
"""
1932
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
6,308✔
1933
    s, n = Int(start), Int(stop)
586✔
1934
    B = similar(A)
6,309✔
1935
    for i = firstindex(A):s-1
6,312✔
1936
        B[i] = A[i]
14✔
1937
    end
24✔
1938
    for i = s:n
12,608✔
1939
        B[i] = A[n+s-i]
281,324✔
1940
    end
556,344✔
1941
    for i = n+1:lastindex(A)
6,312✔
1942
        B[i] = A[i]
20✔
1943
    end
36✔
1944
    return B
6,308✔
1945
end
1946

1947
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
1948
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
1949
    @eval begin
1950
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
106,464,020✔
1951
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
8,941✔
1952
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
1953
        function $_f(A::AbstractVector, dim::Integer)
7✔
1954
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
1955
            return $_f(A, :)
4✔
1956
        end
1957
    end
1958
end
1959

1960
function reverseind(a::AbstractVector, i::Integer)
3✔
1961
    li = LinearIndices(a)
3✔
1962
    first(li) + last(li) - i
3✔
1963
end
1964

1965
# This implementation of `midpoint` is performance-optimized but safe
1966
# only if `lo <= hi`.
1967
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
16,397,509✔
1968
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
1969

1970
"""
1971
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
1972

1973
In-place version of [`reverse`](@ref).
1974

1975
# Examples
1976
```jldoctest
1977
julia> A = Vector(1:5)
1978
5-element Vector{Int64}:
1979
 1
1980
 2
1981
 3
1982
 4
1983
 5
1984

1985
julia> reverse!(A);
1986

1987
julia> A
1988
5-element Vector{Int64}:
1989
 5
1990
 4
1991
 3
1992
 2
1993
 1
1994
```
1995
"""
1996
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
157,525✔
1997
    s, n = Int(start), Int(stop)
32,702✔
1998
    if n > s # non-empty and non-trivial
157,522✔
1999
        liv = LinearIndices(v)
151,955✔
2000
        if !(first(liv) ≤ s ≤ last(liv))
151,955✔
2001
            throw(BoundsError(v, s))
3✔
2002
        elseif !(first(liv) ≤ n ≤ last(liv))
151,952✔
2003
            throw(BoundsError(v, n))
1✔
2004
        end
2005
        r = n
30,903✔
2006
        @inbounds for i in s:midpoint(s, n-1)
303,902✔
2007
            v[i], v[r] = v[r], v[i]
2,033,285✔
2008
            r -= 1
2,029,023✔
2009
        end
3,906,095✔
2010
    end
2011
    return v
157,518✔
2012
end
2013

2014
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2015

2016
vcat() = Vector{Any}()
8,886✔
2017
hcat() = Vector{Any}()
1✔
2018

2019
function hcat(V::Vector{T}...) where T
560✔
2020
    height = length(V[1])
560✔
2021
    for j = 2:length(V)
561✔
2022
        if length(V[j]) != height
626✔
2023
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2024
        end
2025
    end
723✔
2026
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
559✔
2027
end
2028
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
5✔
2029

2030
function vcat(arrays::Vector{T}...) where T
34,993✔
2031
    n = 0
10,036✔
2032
    for a in arrays
34,993✔
2033
        n += length(a)
2,070,143✔
2034
    end
2,105,121✔
2035
    arr = Vector{T}(undef, n)
34,993✔
2036
    nd = 1
10,036✔
2037
    for a in arrays
34,993✔
2038
        na = length(a)
2,070,143✔
2039
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,070,143✔
2040
        unsafe_copyto!(arr, nd, a, 1, na)
2,070,143✔
2041
        nd += na
2,070,143✔
2042
    end
2,105,121✔
2043
    return arr
34,993✔
2044
end
2045
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
33✔
2046

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

2049
## find ##
2050

2051
"""
2052
    findnext(A, i)
2053

2054
Find the next index after or including `i` of a `true` element of `A`,
2055
or `nothing` if not found.
2056

2057
Indices are of the same type as those returned by [`keys(A)`](@ref)
2058
and [`pairs(A)`](@ref).
2059

2060
# Examples
2061
```jldoctest
2062
julia> A = [false, false, true, false]
2063
4-element Vector{Bool}:
2064
 0
2065
 0
2066
 1
2067
 0
2068

2069
julia> findnext(A, 1)
2070
3
2071

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

2074
julia> A = [false false; true false]
2075
2×2 Matrix{Bool}:
2076
 0  0
2077
 1  0
2078

2079
julia> findnext(A, CartesianIndex(1, 1))
2080
CartesianIndex(2, 1)
2081
```
2082
"""
2083
findnext(A, start) = findnext(identity, A, start)
77,984✔
2084

2085
"""
2086
    findfirst(A)
2087

2088
Return the index or key of the first `true` value in `A`.
2089
Return `nothing` if no such value is found.
2090
To search for other kinds of values, pass a predicate as the first argument.
2091

2092
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2093
and [`pairs(A)`](@ref).
2094

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

2097
# Examples
2098
```jldoctest
2099
julia> A = [false, false, true, false]
2100
4-element Vector{Bool}:
2101
 0
2102
 0
2103
 1
2104
 0
2105

2106
julia> findfirst(A)
2107
3
2108

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

2111
julia> A = [false false; true false]
2112
2×2 Matrix{Bool}:
2113
 0  0
2114
 1  0
2115

2116
julia> findfirst(A)
2117
CartesianIndex(2, 1)
2118
```
2119
"""
2120
findfirst(A) = findfirst(identity, A)
2✔
2121

2122
# Needed for bootstrap, and allows defining only an optimized findnext method
2123
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
9,911✔
2124

2125
"""
2126
    findnext(predicate::Function, A, i)
2127

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

2131
Indices are of the same type as those returned by [`keys(A)`](@ref)
2132
and [`pairs(A)`](@ref).
2133

2134
# Examples
2135
```jldoctest
2136
julia> A = [1, 4, 2, 2];
2137

2138
julia> findnext(isodd, A, 1)
2139
1
2140

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

2143
julia> A = [1 4; 2 2];
2144

2145
julia> findnext(isodd, A, CartesianIndex(1, 1))
2146
CartesianIndex(1, 1)
2147
```
2148
"""
2149
function findnext(testf::Function, A, start)
51,163✔
2150
    i = oftype(first(keys(A)), start)
50,655✔
2151
    l = last(keys(A))
67,014,820✔
2152
    i > l && return nothing
67,014,820✔
2153
    while true
172,355,349✔
2154
        testf(A[i]) && return i
172,360,789✔
2155
        i == l && break
166,908,059✔
2156
        # nextind(A, l) can throw/overflow
2157
        i = nextind(A, i)
162,629,756✔
2158
    end
162,629,737✔
2159
    return nothing
4,278,298✔
2160
end
2161

2162
"""
2163
    findfirst(predicate::Function, A)
2164

2165
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2166
Return `nothing` if there is no such element.
2167

2168
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2169
and [`pairs(A)`](@ref).
2170

2171
# Examples
2172
```jldoctest
2173
julia> A = [1, 4, 2, 2]
2174
4-element Vector{Int64}:
2175
 1
2176
 4
2177
 2
2178
 2
2179

2180
julia> findfirst(iseven, A)
2181
2
2182

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

2185
julia> findfirst(isequal(4), A)
2186
2
2187

2188
julia> A = [1 4; 2 2]
2189
2×2 Matrix{Int64}:
2190
 1  4
2191
 2  2
2192

2193
julia> findfirst(iseven, A)
2194
CartesianIndex(2, 1)
2195
```
2196
"""
2197
function findfirst(testf::Function, A)
14✔
2198
    for (i, a) in pairs(A)
22✔
2199
        testf(a) && return i
14✔
2200
    end
11✔
2201
    return nothing
7✔
2202
end
2203

2204
# Needed for bootstrap, and allows defining only an optimized findnext method
2205
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
240,037,219✔
2206
    findnext(testf, A, first(keys(A)))
2207

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

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

2214
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2215
    isempty(r) && return nothing
6✔
2216
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2217
    d = convert(S, p.x - first(r))::S
3✔
2218
    iszero(d % step(r)) || return nothing
3✔
2219
    return d ÷ step(r) + 1
3✔
2220
end
2221

2222
"""
2223
    findprev(A, i)
2224

2225
Find the previous index before or including `i` of a `true` element of `A`,
2226
or `nothing` if not found.
2227

2228
Indices are of the same type as those returned by [`keys(A)`](@ref)
2229
and [`pairs(A)`](@ref).
2230

2231
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2232

2233
# Examples
2234
```jldoctest
2235
julia> A = [false, false, true, true]
2236
4-element Vector{Bool}:
2237
 0
2238
 0
2239
 1
2240
 1
2241

2242
julia> findprev(A, 3)
2243
3
2244

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

2247
julia> A = [false false; true true]
2248
2×2 Matrix{Bool}:
2249
 0  0
2250
 1  1
2251

2252
julia> findprev(A, CartesianIndex(2, 1))
2253
CartesianIndex(2, 1)
2254
```
2255
"""
2256
findprev(A, start) = findprev(identity, A, start)
12,283✔
2257

2258
"""
2259
    findlast(A)
2260

2261
Return the index or key of the last `true` value in `A`.
2262
Return `nothing` if there is no `true` value in `A`.
2263

2264
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2265
and [`pairs(A)`](@ref).
2266

2267
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2268

2269
# Examples
2270
```jldoctest
2271
julia> A = [true, false, true, false]
2272
4-element Vector{Bool}:
2273
 1
2274
 0
2275
 1
2276
 0
2277

2278
julia> findlast(A)
2279
3
2280

2281
julia> A = falses(2,2);
2282

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

2285
julia> A = [true false; true false]
2286
2×2 Matrix{Bool}:
2287
 1  0
2288
 1  0
2289

2290
julia> findlast(A)
2291
CartesianIndex(2, 1)
2292
```
2293
"""
2294
findlast(A) = findlast(identity, A)
23✔
2295

2296
# Needed for bootstrap, and allows defining only an optimized findprev method
2297
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
4,096✔
2298

2299
"""
2300
    findprev(predicate::Function, A, i)
2301

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

2305
Indices are of the same type as those returned by [`keys(A)`](@ref)
2306
and [`pairs(A)`](@ref).
2307

2308
# Examples
2309
```jldoctest
2310
julia> A = [4, 6, 1, 2]
2311
4-element Vector{Int64}:
2312
 4
2313
 6
2314
 1
2315
 2
2316

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

2319
julia> findprev(isodd, A, 3)
2320
3
2321

2322
julia> A = [4 6; 1 2]
2323
2×2 Matrix{Int64}:
2324
 4  6
2325
 1  2
2326

2327
julia> findprev(isodd, A, CartesianIndex(1, 2))
2328
CartesianIndex(2, 1)
2329
```
2330
"""
2331
function findprev(testf::Function, A, start)
36,711✔
2332
    f = first(keys(A))
36,711✔
2333
    i = oftype(f, start)
36,722✔
2334
    i < f && return nothing
38,273✔
2335
    while true
184,864✔
2336
        testf(A[i]) && return i
184,903✔
2337
        i == f && break
146,683✔
2338
        # prevind(A, f) can throw/underflow
2339
        i = prevind(A, i)
146,620✔
2340
    end
146,592✔
2341
    return nothing
60✔
2342
end
2343

2344
"""
2345
    findlast(predicate::Function, A)
2346

2347
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2348
Return `nothing` if there is no such element.
2349

2350
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2351
and [`pairs(A)`](@ref).
2352

2353
# Examples
2354
```jldoctest
2355
julia> A = [1, 2, 3, 4]
2356
4-element Vector{Int64}:
2357
 1
2358
 2
2359
 3
2360
 4
2361

2362
julia> findlast(isodd, A)
2363
3
2364

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

2367
julia> A = [1 2; 3 4]
2368
2×2 Matrix{Int64}:
2369
 1  2
2370
 3  4
2371

2372
julia> findlast(isodd, A)
2373
CartesianIndex(2, 1)
2374
```
2375
"""
2376
function findlast(testf::Function, A)
4✔
2377
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2378
        testf(a) && return i
6✔
2379
    end
6✔
2380
    return nothing
2✔
2381
end
2382

2383
# Needed for bootstrap, and allows defining only an optimized findprev method
2384
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
13,560✔
2385
    findprev(testf, A, last(keys(A)))
2386

2387
"""
2388
    findall(f::Function, A)
2389

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

2393
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2394
and [`pairs(A)`](@ref).
2395

2396
# Examples
2397
```jldoctest
2398
julia> x = [1, 3, 4]
2399
3-element Vector{Int64}:
2400
 1
2401
 3
2402
 4
2403

2404
julia> findall(isodd, x)
2405
2-element Vector{Int64}:
2406
 1
2407
 2
2408

2409
julia> A = [1 2 0; 3 4 0]
2410
2×3 Matrix{Int64}:
2411
 1  2  0
2412
 3  4  0
2413
julia> findall(isodd, A)
2414
2-element Vector{CartesianIndex{2}}:
2415
 CartesianIndex(1, 1)
2416
 CartesianIndex(2, 1)
2417

2418
julia> findall(!iszero, A)
2419
4-element Vector{CartesianIndex{2}}:
2420
 CartesianIndex(1, 1)
2421
 CartesianIndex(2, 1)
2422
 CartesianIndex(1, 2)
2423
 CartesianIndex(2, 2)
2424

2425
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2426
Dict{Symbol, Int64} with 3 entries:
2427
  :A => 10
2428
  :B => -1
2429
  :C => 0
2430

2431
julia> findall(x -> x >= 0, d)
2432
2-element Vector{Symbol}:
2433
 :A
2434
 :C
2435

2436
```
2437
"""
2438
function findall(testf::Function, A)
57✔
2439
    gen = (first(p) for p in pairs(A) if testf(last(p)))
57✔
2440
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
×
2441
end
2442

2443
# Broadcasting is much faster for small testf, and computing
2444
# integer indices from logical index using findall has a negligible cost
2445
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
317✔
2446

2447
"""
2448
    findall(A)
2449

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

2454
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2455
and [`pairs(A)`](@ref).
2456

2457
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2458

2459
# Examples
2460
```jldoctest
2461
julia> A = [true, false, false, true]
2462
4-element Vector{Bool}:
2463
 1
2464
 0
2465
 0
2466
 1
2467

2468
julia> findall(A)
2469
2-element Vector{Int64}:
2470
 1
2471
 4
2472

2473
julia> A = [true false; false true]
2474
2×2 Matrix{Bool}:
2475
 1  0
2476
 0  1
2477

2478
julia> findall(A)
2479
2-element Vector{CartesianIndex{2}}:
2480
 CartesianIndex(1, 1)
2481
 CartesianIndex(2, 2)
2482

2483
julia> findall(falses(3))
2484
Int64[]
2485
```
2486
"""
2487
function findall(A)
3✔
2488
    collect(first(p) for p in pairs(A) if last(p))
3✔
2489
end
2490

2491
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2492
function findall(A::AbstractArray{Bool})
2,827✔
2493
    n = count(A)
2,832✔
2494
    I = Vector{eltype(keys(A))}(undef, n)
2,827✔
2495
    cnt = 1
2,827✔
2496
    for (i,a) in pairs(A)
5,646✔
2497
        if a
125,610✔
2498
            I[cnt] = i
62,449✔
2499
            cnt += 1
62,449✔
2500
        end
2501
    end
248,398✔
2502
    I
2,827✔
2503
end
2504

2505
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2506
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2507
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2508

2509
# similar to Matlab's ismember
2510
"""
2511
    indexin(a, b)
2512

2513
Return an array containing the first index in `b` for
2514
each value in `a` that is a member of `b`. The output
2515
array contains `nothing` wherever `a` is not a member of `b`.
2516

2517
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2518

2519
# Examples
2520
```jldoctest
2521
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2522

2523
julia> b = ['a', 'b', 'c'];
2524

2525
julia> indexin(a, b)
2526
6-element Vector{Union{Nothing, Int64}}:
2527
 1
2528
 2
2529
 3
2530
 2
2531
  nothing
2532
 1
2533

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

2552
function _findin(a::Union{AbstractArray, Tuple}, b)
13✔
2553
    ind  = Vector{eltype(keys(a))}()
13✔
2554
    bset = Set(b)
15✔
2555
    @inbounds for (i,ai) in pairs(a)
25✔
2556
        ai in bset && push!(ind, i)
91✔
2557
    end
94✔
2558
    ind
13✔
2559
end
2560

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

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

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

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

2641
## Filter ##
2642

2643
"""
2644
    filter(f, a)
2645

2646
Return a copy of collection `a`, removing elements for which `f` is `false`.
2647
The function `f` is passed one argument.
2648

2649
!!! compat "Julia 1.4"
2650
    Support for `a` as a tuple requires at least Julia 1.4.
2651

2652
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2653

2654
# Examples
2655
```jldoctest
2656
julia> a = 1:10
2657
1:10
2658

2659
julia> filter(isodd, a)
2660
5-element Vector{Int64}:
2661
 1
2662
 3
2663
 5
2664
 7
2665
 9
2666
```
2667
"""
2668
function filter(f, a::Array{T, N}) where {T, N}
192,487✔
2669
    j = 1
173,087✔
2670
    b = Vector{T}(undef, length(a))
192,487✔
2671
    for ai in a
192,887✔
2672
        @inbounds b[j] = ai
3,241,695✔
2673
        j = ifelse(f(ai)::Bool, j+1, j)
3,243,937✔
2674
    end
3,433,720✔
2675
    resize!(b, j-1)
384,974✔
2676
    sizehint!(b, length(b))
192,487✔
2677
    b
192,487✔
2678
end
2679

2680
function filter(f, a::AbstractArray)
374✔
2681
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
374✔
2682

2683
    j = 1
374✔
2684
    idxs = Vector{Int}(undef, length(a))
377✔
2685
    for idx in eachindex(a)
626✔
2686
        @inbounds idxs[j] = idx
103,147✔
2687
        ai = @inbounds a[idx]
103,147✔
2688
        j = ifelse(f(ai)::Bool, j+1, j)
138,393✔
2689
    end
206,041✔
2690
    resize!(idxs, j-1)
746✔
2691
    res = a[idxs]
373✔
2692
    empty!(idxs)
373✔
2693
    sizehint!(idxs, 0)
373✔
2694
    return res
373✔
2695
end
2696

2697
"""
2698
    filter!(f, a)
2699

2700
Update collection `a`, removing elements for which `f` is `false`.
2701
The function `f` is passed one argument.
2702

2703
# Examples
2704
```jldoctest
2705
julia> filter!(isodd, Vector(1:10))
2706
5-element Vector{Int64}:
2707
 1
2708
 3
2709
 5
2710
 7
2711
 9
2712
```
2713
"""
2714
function filter!(f, a::AbstractVector)
69,568,989✔
2715
    j = firstindex(a)
453,858✔
2716
    for ai in a
75,694,380✔
2717
        @inbounds a[j] = ai
85,423,033✔
2718
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
88,272,909✔
2719
    end
148,866,641✔
2720
    j > lastindex(a) && return a
69,568,989✔
2721
    if a isa Vector
453,238✔
2722
        resize!(a, j-1)
1,001,181✔
2723
        sizehint!(a, j-1)
500,591✔
2724
    else
2725
        deleteat!(a, j:lastindex(a))
1✔
2726
    end
2727
    return a
500,592✔
2728
end
2729

2730
"""
2731
    filter(f)
2732

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

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

2739
# Examples
2740
```jldoctest
2741
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2742
(1, 2, 4, 6)
2743

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

2757
"""
2758
    keepat!(a::Vector, inds)
2759
    keepat!(a::BitVector, inds)
2760

2761
Remove the items at all the indices which are not given by `inds`,
2762
and return the modified `a`.
2763
Items which are kept are shifted to fill the resulting gaps.
2764

2765
`inds` must be an iterator of sorted and unique integer indices.
2766
See also [`deleteat!`](@ref).
2767

2768
!!! compat "Julia 1.7"
2769
    This function is available as of Julia 1.7.
2770

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

2782
"""
2783
    keepat!(a::Vector, m::AbstractVector{Bool})
2784
    keepat!(a::BitVector, m::AbstractVector{Bool})
2785

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

2790
# Examples
2791
```jldoctest
2792
julia> a = [:a, :b, :c];
2793

2794
julia> keepat!(a, [true, false, true])
2795
2-element Vector{Symbol}:
2796
 :a
2797
 :c
2798

2799
julia> a
2800
2-element Vector{Symbol}:
2801
 :a
2802
 :c
2803
```
2804
"""
2805
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
2806

2807
# set-like operators for vectors
2808
# These are moderately efficient, preserve order, and remove dupes.
2809

2810
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
16,760✔
2811
    # P, U force specialization
2812
    if pred(x, state)
29,593✔
2813
        update!(state, x)
7,593✔
2814
        true
7,593✔
2815
    else
2816
        false
8,182✔
2817
    end
2818
end
2819

2820
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
242✔
2821
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
1,162✔
2822

2823
function _grow!(pred!, v::AbstractVector, itrs)
267✔
2824
    filter!(pred!, v) # uniquify v
269✔
2825
    for itr in itrs
269✔
2826
        mapfilter(pred!, push!, itr, v)
525✔
2827
    end
774✔
2828
    return v
269✔
2829
end
2830

2831
union!(v::AbstractVector{T}, itrs...) where {T} =
236✔
2832
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
2833

2834
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
2835
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
2836

2837
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
6✔
2838
    seen = Set{eltype(v)}()
6✔
2839
    filter!(_grow_filter!(seen), v)
6✔
2840
    shrinker!(seen, itrs...)
7✔
2841
    filter!(in(seen), v)
6✔
2842
end
2843

2844
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
2845
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
2846

2847
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
1,130✔
2848

2849
function _shrink(shrinker!::F, itr, itrs) where F
1,070✔
2850
    T = promote_eltype(itr, itrs...)
908✔
2851
    keep = shrinker!(Set{T}(itr), itrs...)
2,550✔
2852
    vectorfilter(T, _shrink_filter!(keep), itr)
1,070✔
2853
end
2854

2855
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
553✔
2856
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
517✔
2857

2858
function intersect(v::AbstractVector, r::AbstractRange)
59✔
2859
    T = promote_eltype(v, r)
11✔
2860
    common = Iterators.filter(in(r), v)
59✔
2861
    seen = Set{T}(common)
59✔
2862
    return vectorfilter(T, _shrink_filter!(seen), common)
59✔
2863
end
2864
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
2865

2866
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
2867
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
27,846,531✔
2868
    if i isa Bool # Not via dispatch to avoid ambiguities
27,846,174✔
2869
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
2870
    else
2871
        _getindex(v, i)
829,967,699✔
2872
    end
2873
end
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