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

JuliaLang / julia / #37801

08 Jun 2024 05:10AM UTC coverage: 87.504% (+0.03%) from 87.474%
#37801

push

local

web-flow
Don't let setglobal! implicitly create bindings (#54678)

PR #44231 (part of Julia 1.9) introduced the ability to modify globals
with `Mod.sym = val` syntax. However, the intention of this syntax was
always to modify *existing* globals in other modules. Unfortunately, as
implemented, it also implicitly creates new bindings in the other
module, even if the binding was not previously declared. This was not
intended, but it's a bit of a syntax corner case, so nobody caught it at
the time.

After some extensive discussions and taking into account the near future
direction we want to go with bindings (#54654 for both), the consensus
was reached that we should try to undo the implicit creation of bindings
(but not the ability to assign the *value* of globals in other modules).
Note that this was always an error until Julia 1.9, so hopefully it
hasn't crept into too many packages yet. We'll see what pkgeval says. If
use is extensive, we may want to consider a softer removal strategy.

Across base and stdlib, there's two cases affected by this change:
1. A left over debug statement in `precompile` that wanted to assign a
new variable in Base for debugging. Removed in this PR.
2. Distributed wanting to create new bindings. This is a legimitate use
case for wanting to create bindings in other modules. This is fixed in
https://github.com/JuliaLang/Distributed.jl/pull/102.

As noted in that PR, the recommended replacement where implicit binding
creation is desired is:
```
Core.eval(mod, Expr(:global, sym))
invokelatest(setglobal!, mod, sym, val)
```

The `invokelatest` is not presently required, but may be needed by
#54654, so it's included in the recommendation now.

Fixes #54607

77035 of 88036 relevant lines covered (87.5%)

16049112.75 hits per line

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

93.89
/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,596✔
13
end
14
DimensionMismatch() = DimensionMismatch("")
×
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
"""
124
    @_safeindex
125

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

158
vect() = Vector{Any}()
623,596✔
159
function vect(X::T...) where T
50,748✔
160
    @_terminates_locally_meta
103,013✔
161
    vec = Vector{T}(undef, length(X))
1,674,433✔
162
    @_safeindex for i = 1:length(X)
230,674✔
163
        vec[i] = X[i]
4,779,996✔
164
    end
6,495,501✔
165
    return vec
185,619✔
166
end
167

168
"""
169
    vect(X...)
170

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

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

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
10,560✔
190
    d < 1 && error("arraysize: dimension out of range")
65,367,325✔
191
    sz = getfield(a, :size)
65,487,571✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
97,681,612✔
193
end
194
size(a::Array) = getfield(a, :size)
2,147,483,647✔
195

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

198
allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0))
15,799✔
199

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

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

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

210
julia> Base.isbitsunion(Union{Float64, String})
211
false
212
```
213
"""
214
isbitsunion(u::Type) = u isa Union && allocatedinline(u)
36,405✔
215

216
function _unsetindex!(A::Array, i::Int)
217
    @inline
10,983,867✔
218
    @boundscheck checkbounds(A, i)
2,147,483,647✔
219
    @inbounds _unsetindex!(memoryref(A.ref, i))
2,147,483,647✔
220
    return A
2,147,483,647✔
221
end
222

223

224
# TODO: deprecate this (aligned_sizeof and/or elsize and/or sizeof(Some{T}) are more correct)
225
elsize(::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
357,919✔
226
function elsize(::Type{Ptr{T}}) where T
8✔
227
    # this only must return something valid for values which satisfy is_valid_intrinsic_elptr(T),
228
    # which includes Any and most concrete datatypes
229
    T === Any && return sizeof(Ptr{Any})
8✔
230
    T isa DataType || sizeof(Any) # throws
7✔
231
    return LLT_ALIGN(Core.sizeof(T), datatype_alignment(T))
5✔
232
end
233
elsize(::Type{Union{}}, slurp...) = 0
×
234

235
sizeof(a::Array) = length(a) * elsize(typeof(a)) # n.b. this ignores bitsunion bytes, as a historical fact
2,779,371✔
236

237
function isassigned(a::Array, i::Int...)
110,310✔
238
    @inline
445,458✔
239
    @_noub_if_noinbounds_meta
445,458✔
240
    @boundscheck checkbounds(Bool, a, i...) || return false
445,470✔
241
    ii = _sub2ind(size(a), i...)
445,450✔
242
    return @inbounds isassigned(memoryrefnew(a.ref, ii, false))
445,450✔
243
end
244

245
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
165✔
246
    @inline
6,092,990✔
247
    @_noub_if_noinbounds_meta
6,092,990✔
248
    @boundscheck checkbounds(Bool, a, i) || return false
2,147,483,647✔
249
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
2,147,483,647✔
250
end
251

252

253
## copy ##
254

255
"""
256
    unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
257

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

261
The `unsafe` prefix on this function indicates that no validation is performed on the
262
pointers `dest` and `src` to ensure that they are valid. Incorrect usage may corrupt or
263
segfault your program, in the same manner as C.
264
"""
265
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
266
    # Do not use this to copy data between pointer arrays.
267
    # It can't be made safe no matter how carefully you checked.
268
    memmove(dest, src, n * aligned_sizeof(T))
31,496,231✔
269
    return dest
30,681,528✔
270
end
271

272
"""
273
    unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
274

275
Copy `n` elements from a source array to a destination, starting at the linear index `soffs` in the
276
source and `doffs` in the destination (1-indexed).
277

278
The `unsafe` prefix on this function indicates that no validation is performed to ensure
279
that n is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
280
the same manner as C.
281
"""
282
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
283
    n == 0 && return dest
12,924,423✔
284
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
15,790,716✔
285
    return dest
7,895,361✔
286
end
287

288
"""
289
    copyto!(dest, doffs, src, soffs, n)
290

291
Copy `n` elements from collection `src` starting at the linear index `soffs`, to array `dest` starting at
292
the index `doffs`. Return `dest`.
293
"""
294
copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
62,490✔
295
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
17✔
296
copyto!(dest::Memory, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
×
297

298
# this is only needed to avoid possible ambiguities with methods added in some packages
299
copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where {T} = _copyto_impl!(dest, doffs, src, soffs, n)
264,659,181✔
300

301
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
11✔
302
    n == 0 && return dest
162,866,815✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
126,478,961✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
126,478,980✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
126,478,941✔
306
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
126,478,946✔
307
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
252,957,832✔
309
    end
310
    return dest
126,478,694✔
311
end
312

313

314
# Outlining this because otherwise a catastrophic inference slowdown
315
# occurs, see discussion in #27874.
316
# It is also mitigated by using a constant string.
317
_throw_argerror(s) = (@noinline; throw(ArgumentError(s)))
10✔
318

319
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
35,210✔
320

321
# also to avoid ambiguities in packages
322
copyto!(dest::Array{T}, src::Array{T}) where {T} = copyto!(dest, 1, src, 1, length(src))
39,805,966✔
323

324
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
325
# for bootstrapping purposes.
326
function fill!(dest::Array{T}, x) where T
997✔
327
    xT = x isa T ? x : convert(T, x)::T
256,662✔
328
    for i in eachindex(dest)
908,246,297✔
329
        @inbounds dest[i] = xT
2,147,483,647✔
330
    end
2,147,483,647✔
331
    return dest
908,246,297✔
332
end
333

334
"""
335
    copy(x)
336

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

341
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
342
"""
343
copy
344

345
@eval function copy(a::Array{T}) where {T}
148,103✔
346
    # `jl_genericmemory_copy_slice` only throws when the size exceeds the max allocation
347
    # size, but since we're copying an existing array, we're guaranteed that this will not happen.
348
    @_nothrow_meta
280,519✔
349
    ref = a.ref
185,063,880✔
350
    newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a))
185,063,882✔
351
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
185,063,763✔
352
end
353

354
## Constructors ##
355

356
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
238,463✔
357
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
8,053✔
358
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
16,683✔
359
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
24,056✔
360
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
4,371,530✔
361
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
108,932,550✔
362
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
643✔
363

364
# T[x...] constructs Array{T,1}
365
"""
366
    getindex(type[, elements...])
367

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

371
# Examples
372
```jldoctest
373
julia> Int8[1, 2, 3]
374
3-element Vector{Int8}:
375
 1
376
 2
377
 3
378

379
julia> getindex(Int8, 1, 2, 3)
380
3-element Vector{Int8}:
381
 1
382
 2
383
 3
384
```
385
"""
386
function getindex(::Type{T}, vals...) where T
59,067✔
387
    @inline
153,012✔
388
    @_effect_free_terminates_locally_meta
153,012✔
389
    a = Vector{T}(undef, length(vals))
984,442,929✔
390
    if vals isa NTuple
153,044✔
391
        @_safeindex for i in 1:length(vals)
97,516✔
392
            a[i] = vals[i]
66,939,828✔
393
        end
240,727✔
394
    else
395
        # use afoldl to avoid type instability inside loop
396
        afoldl(1, vals...) do i, v
58,695✔
397
            @inbounds a[i] = v
123,066✔
398
            return i + 1
123,052✔
399
        end
400
    end
401
    return a
156,261✔
402
end
403

404
function getindex(::Type{Any}, @nospecialize vals...)
24,316,219✔
405
    @_effect_free_terminates_locally_meta
692✔
406
    a = Vector{Any}(undef, length(vals))
93,430,571✔
407
    @_safeindex for i = 1:length(vals)
31,226,454✔
408
        a[i] = vals[i]
124,650,555✔
409
    end
121,636,024✔
410
    return a
24,524,920✔
411
end
412
getindex(::Type{Any}) = Vector{Any}()
76,328,315✔
413

414
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
5✔
415
    ref = a.ref
11,402,712✔
416
    t = @_gc_preserve_begin ref
11,402,712✔
417
    p = unsafe_convert(Ptr{Cvoid}, ref)
11,402,712✔
418
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
11,402,715✔
419
    @_gc_preserve_end t
11,402,709✔
420
    return a
11,402,709✔
421
end
422

423
to_dim(d::Integer) = d
×
424
to_dim(d::OneTo) = last(d)
209✔
425

426
"""
427
    fill(value, dims::Tuple)
428
    fill(value, dims...)
429

430
Create an array of size `dims` with every location set to `value`.
431

432
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
433
with `1.0` in every location of the array.
434

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

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

448
```jldoctest
449
julia> v = fill([], 3)
450
3-element Vector{Vector{Any}}:
451
 []
452
 []
453
 []
454

455
julia> v[1] === v[2] === v[3]
456
true
457

458
julia> value = v[1]
459
Any[]
460

461
julia> push!(value, 867_5309)
462
1-element Vector{Any}:
463
 8675309
464

465
julia> v
466
3-element Vector{Vector{Any}}:
467
 [8675309]
468
 [8675309]
469
 [8675309]
470
```
471

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

475
```jldoctest
476
julia> v2 = [[] for _ in 1:3]
477
3-element Vector{Vector{Any}}:
478
 []
479
 []
480
 []
481

482
julia> v2[1] === v2[2] === v2[3]
483
false
484

485
julia> push!(v2[1], 8675309)
486
1-element Vector{Any}:
487
 8675309
488

489
julia> v2
490
3-element Vector{Vector{Any}}:
491
 [8675309]
492
 []
493
 []
494
```
495

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

498
# Examples
499
```jldoctest
500
julia> fill(1.0, (2,3))
501
2×3 Matrix{Float64}:
502
 1.0  1.0  1.0
503
 1.0  1.0  1.0
504

505
julia> fill(42)
506
0-dimensional Array{Int64, 0}:
507
42
508

509
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
510
2-element Vector{Vector{Float64}}:
511
 [0.0, 0.0]
512
 [0.0, 0.0]
513

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

516
julia> A # both A[1] and A[2] are the very same vector
517
2-element Vector{Vector{Float64}}:
518
 [42.0, 0.0]
519
 [42.0, 0.0]
520
```
521
"""
522
function fill end
523

524
fill(v, dims::DimOrInd...) = fill(v, dims)
2,147,483,647✔
525
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
526
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
2,147,483,647✔
527
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
×
528
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
137✔
529

530
"""
531
    zeros([T=Float64,] dims::Tuple)
532
    zeros([T=Float64,] dims...)
533

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

537
# Examples
538
```jldoctest
539
julia> zeros(1)
540
1-element Vector{Float64}:
541
 0.0
542

543
julia> zeros(Int8, 2, 3)
544
2×3 Matrix{Int8}:
545
 0  0  0
546
 0  0  0
547
```
548
"""
549
function zeros end
550

551
"""
552
    ones([T=Float64,] dims::Tuple)
553
    ones([T=Float64,] dims...)
554

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

558
# Examples
559
```jldoctest
560
julia> ones(1,2)
561
1×2 Matrix{Float64}:
562
 1.0  1.0
563

564
julia> ones(ComplexF64, 2, 3)
565
2×3 Matrix{ComplexF64}:
566
 1.0+0.0im  1.0+0.0im  1.0+0.0im
567
 1.0+0.0im  1.0+0.0im  1.0+0.0im
568
```
569
"""
570
function ones end
571

572
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
573
    @eval begin
574
        $fname(dims::DimOrInd...) = $fname(dims)
20,452,728✔
575
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
2,147,483,647✔
576
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,452,842✔
577
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,261✔
578
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
12,184✔
579
            a = Array{T,N}(undef, dims)
186,667,603✔
580
            fill!(a, $felt(T))
2,147,483,647✔
581
            return a
129,881,699✔
582
        end
583
        function $fname(::Type{T}, dims::Tuple{}) where {T}
584
            a = Array{T}(undef)
20✔
585
            fill!(a, $felt(T))
20✔
586
            return a
20✔
587
        end
588
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
×
589
            a = similar(Array{T,N}, dims)
×
590
            fill!(a, $felt(T))
×
591
            return a
×
592
        end
593
    end
594
end
595

596
## Conversions ##
597

598
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
291,686✔
599

600
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
96✔
601

602
## Constructors ##
603

604
if nameof(@__MODULE__) === :Base  # avoid method overwrite
605
# constructors should make copies
606
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
300,879✔
607
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
9,976✔
608
end
609

610
## copying iterators to containers
611

612
"""
613
    collect(element_type, collection)
614

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

618
# Examples
619
```jldoctest
620
julia> collect(Float64, 1:2:5)
621
3-element Vector{Float64}:
622
 1.0
623
 3.0
624
 5.0
625
```
626
"""
627
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
27,102,285✔
628

629
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
39,609✔
630
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
631
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
27,062,668✔
632
    a = Vector{T}()
27,062,676✔
633
    for x in itr
46,565,875✔
634
        push!(a, x)
131,708,632✔
635
    end
243,914,064✔
636
    return a
27,062,676✔
637
end
638

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

642
_similar_shape(itr, ::SizeUnknown) = nothing
×
643
_similar_shape(itr, ::HasLength) = length(itr)::Integer
54,520,105✔
644
_similar_shape(itr, ::HasShape) = axes(itr)
632,861,304✔
645

646
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,268,278✔
647
    similar(c, T, 0)
648
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
14,559,540✔
649
    similar(c, T, len)
650
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
302,326✔
651
    similar(c, T, axs)
652

653
# make a collection appropriate for collecting `itr::Generator`
654
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
256✔
655
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
66,260,361✔
656
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
1,115,663,659✔
657

658
# used by syntax lowering for simple typed comprehensions
659
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
1,180,269,061✔
660

661

662
"""
663
    collect(collection)
664

665
Return an `Array` of all items in a collection or iterator. For dictionaries, returns
666
a `Vector` of `key=>value` [Pair](@ref Pair)s. If the argument is array-like or is an iterator
667
with the [`HasShape`](@ref IteratorSize) trait, the result will have the same shape
668
and number of dimensions as the argument.
669

670
Used by [comprehensions](@ref man-comprehensions) to turn a [generator expression](@ref man-generators)
671
into an `Array`. Thus, *on generators*, the square-brackets notation may be used instead of calling `collect`,
672
see second example.
673

674
# Examples
675

676
Collect items from a `UnitRange{Int64}` collection:
677

678
```jldoctest
679
julia> collect(1:3)
680
3-element Vector{Int64}:
681
 1
682
 2
683
 3
684
```
685

686
Collect items from a generator (same output as `[x^2 for x in 1:3]`):
687

688
```jldoctest
689
julia> collect(x^2 for x in 1:3)
690
3-element Vector{Int64}:
691
 1
692
 4
693
 9
694
```
695
"""
696
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
16,047,026✔
697

698
collect(A::AbstractArray) = _collect_indices(axes(A), A)
127,825✔
699

700
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
192,229✔
701

702
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
14,546,483✔
703
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
704

705
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,268,170✔
706
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,268,202✔
707
    for x in itr
2,534,343✔
708
        push!(a,x)
10,483,231✔
709
    end
18,056,200✔
710
    return a
1,268,201✔
711
end
712

713
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
714
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
129,201✔
715
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
716
function _collect_indices(indsA, A)
27✔
717
    B = Array{eltype(A)}(undef, length.(indsA))
237✔
718
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
719
end
720

721
# NOTE: this function is not meant to be called, only inferred, for the
722
# purpose of bounding the types of values generated by an iterator.
723
function _iterator_upper_bound(itr)
×
724
    x = iterate(itr)
×
725
    while x !== nothing
×
726
        val = getfield(x, 1)
×
727
        if inferencebarrier(nothing)
×
728
            return val
×
729
        end
730
        x = iterate(itr, getfield(x, 2))
×
731
    end
×
732
    throw(nothing)
×
733
end
734

735
# define this as a macro so that the call to Core.Compiler
736
# gets inlined into the caller before recursion detection
737
# gets a chance to see it, so that recursive calls to the caller
738
# don't trigger the inference limiter
739
if isdefined(Core, :Compiler)
740
    macro default_eltype(itr)
741
        I = esc(itr)
742
        return quote
743
            if $I isa Generator && ($I).f isa Type
531,312✔
744
                T = ($I).f
12,745✔
745
            else
746
                T = Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)})
518,567✔
747
            end
748
            promote_typejoin_union(T)
531,316✔
749
        end
750
    end
751
else
752
    macro default_eltype(itr)
753
        I = esc(itr)
754
        return quote
755
            if $I isa Generator && ($I).f isa Type
756
                promote_typejoin_union($I.f)
757
            else
758
                Any
759
            end
760
        end
761
    end
762
end
763

764
function collect(itr::Generator)
907,576✔
765
    isz = IteratorSize(itr.iter)
393,794✔
766
    et = @default_eltype(itr)
767
    if isa(isz, SizeUnknown)
393,794✔
768
        return grow_to!(Vector{et}(), itr)
98,212✔
769
    else
770
        shp = _similar_shape(itr, isz)
820,588✔
771
        y = iterate(itr)
1,628,623✔
772
        if y === nothing
819,961✔
773
            return _array_for(et, isz, shp)
946✔
774
        end
775
        v1, st = y
391,854✔
776
        dest = _array_for(typeof(v1), isz, shp)
1,626,148✔
777
        # The typeassert gives inference a helping hand on the element type and dimensionality
778
        # (work-around for #28382)
779
        et′ = et <: Type ? Type : et
391,854✔
780
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
392,005✔
781
        collect_to_with_first!(dest, v1, itr, st)::RT
10,809,019✔
782
    end
783
end
784

785
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
76✔
786
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
787

788
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
192,249✔
789
    et = @default_eltype(itr)
123,276✔
790
    shp = _similar_shape(itr, isz)
192,256✔
791
    y = iterate(itr)
380,944✔
792
    if y === nothing
192,254✔
793
        return _similar_for(c, et, itr, isz, shp)
3,541✔
794
    end
795
    v1, st = y
122,188✔
796
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
297,160✔
797
    # The typeassert gives inference a helping hand on the element type and dimensionality
798
    # (work-around for #28382)
799
    et′ = et <: Type ? Type : et
122,166✔
800
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
122,179✔
801
    collect_to_with_first!(dest, v1, itr, st)::RT
188,713✔
802
end
803

804
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
83,107✔
805
    i1 = first(LinearIndices(dest))
514,020✔
806
    dest[i1] = v1
1,007,728✔
807
    return collect_to!(dest, itr, i1+1, st)
11,651,427✔
808
end
809

810
function collect_to_with_first!(dest, v1, itr, st)
×
811
    push!(dest, v1)
×
812
    return grow_to!(dest, itr, st)
×
813
end
814

815
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
234✔
816
    @inline
364✔
817
    new = similar(dest, promote_typejoin(T, typeof(el)))
816✔
818
    f = first(LinearIndices(dest))
364✔
819
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
813✔
820
    @inbounds new[i] = el
409✔
821
    return new
409✔
822
end
823

824
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
127,009✔
825
    # collect to dest array, checking the type of each result. if a result does not
826
    # match, widen the result type and re-dispatch.
827
    i = offs
514,384✔
828
    while true
91,362,874✔
829
        y = iterate(itr, st)
181,717,989✔
830
        y === nothing && break
91,362,864✔
831
        el, st = y
88,935,027✔
832
        if el isa T
88,944,602✔
833
            @inbounds dest[i] = el
90,354,737✔
834
            i += 1
90,354,737✔
835
        else
836
            new = setindex_widen_up_to(dest, el, i)
409✔
837
            return collect_to!(new, itr, i+1, st)
409✔
838
        end
839
    end
90,354,737✔
840
    return dest
1,007,718✔
841
end
842

843
function grow_to!(dest, itr)
1,222✔
844
    y = iterate(itr)
1,605✔
845
    y === nothing && return dest
1,279✔
846
    dest2 = empty(dest, typeof(y[1]))
353✔
847
    push!(dest2, y[1])
426✔
848
    grow_to!(dest2, itr, y[2])
332✔
849
end
850

851
function push_widen(dest, el)
7✔
852
    @inline
10✔
853
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
11✔
854
    if new isa AbstractSet
10✔
855
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
856
        union!(new, dest)
1✔
857
    else
858
        append!(new, dest)
18✔
859
    end
860
    push!(new, el)
10✔
861
    return new
10✔
862
end
863

864
function grow_to!(dest, itr, st)
329✔
865
    T = eltype(dest)
221✔
866
    y = iterate(itr, st)
597✔
867
    while y !== nothing
4,360✔
868
        el, st = y
2,683✔
869
        if el isa T
2,685✔
870
            push!(dest, el)
4,021✔
871
        else
872
            new = push_widen(dest, el)
13✔
873
            return grow_to!(new, itr, st)
10✔
874
        end
875
        y = iterate(itr, st)
6,164✔
876
    end
4,018✔
877
    return dest
332✔
878
end
879

880
## Iteration ##
881

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

884
## Indexing: getindex ##
885

886
"""
887
    getindex(collection, key...)
888

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

892
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
893

894
# Examples
895
```jldoctest
896
julia> A = Dict("a" => 1, "b" => 2)
897
Dict{String, Int64} with 2 entries:
898
  "b" => 2
899
  "a" => 1
900

901
julia> getindex(A, "a")
902
1
903
```
904
"""
905
function getindex end
906

907
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
119,782✔
908
    @inline
198,425,853✔
909
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
210,731,084✔
910
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
210,731,452✔
911
end
912

913
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
914
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
8,587,189✔
915
    @inline
869,309✔
916
    @boundscheck checkbounds(A, I)
68,757,291✔
917
    lI = length(I)
68,757,300✔
918
    X = similar(A, axes(I))
107,907,809✔
919
    if lI > 0
68,757,289✔
920
        copyto!(X, firstindex(X), A, first(I), lI)
78,301,028✔
921
    end
922
    return X
68,757,289✔
923
end
924

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

928
function getindex(A::Array, c::Colon)
4,450✔
929
    lI = length(A)
2,180,342✔
930
    X = similar(A, lI)
4,360,682✔
931
    if lI > 0
2,180,342✔
932
        unsafe_copyto!(X, 1, A, 1, lI)
4,360,680✔
933
    end
934
    return X
2,180,342✔
935
end
936

937
# This is redundant with the abstract fallbacks, but needed for bootstrap
938
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
141✔
939
    return S[ A[i] for i in I ]
13,028,159✔
940
end
941

942
## Indexing: setindex! ##
943

944
"""
945
    setindex!(collection, value, key...)
946

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

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

956
julia> setindex!(a, 2, "b")
957
Dict{String, Int64} with 2 entries:
958
  "b" => 2
959
  "a" => 1
960
```
961
"""
962
function setindex! end
963

964
function setindex!(A::Array{T}, x, i::Int) where {T}
6,027,271✔
965
    @_noub_if_noinbounds_meta
712,896,467✔
966
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
2,147,483,647✔
967
    memoryrefset!(memoryrefnew(A.ref, i, false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
2,147,483,647✔
968
    return A
2,147,483,647✔
969
end
970
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,503✔
971
    @inline
71,880,039✔
972
    @_noub_if_noinbounds_meta
71,880,039✔
973
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
74,957,474✔
974
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
74,958,324✔
975
    return A
74,957,450✔
976
end
977

978
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
1,402,823✔
979
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
303,912,368✔
980
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
436,293✔
981
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
2,147,483,647✔
982
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
983
    __safe_setindex!(A, convert(T, x)::T, i))
36,128✔
984

985
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
986
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
91✔
987
    @_propagate_inbounds_meta
816,797✔
988
    @boundscheck setindex_shape_check(X, length(I))
9,406,784✔
989
    @boundscheck checkbounds(A, I)
9,406,784✔
990
    require_one_based_indexing(X)
816,797✔
991
    X′ = unalias(A, X)
816,797✔
992
    I′ = unalias(A, I)
816,797✔
993
    count = 1
816,797✔
994
    for i in I′
9,407,044✔
995
        @inbounds A[i] = X′[count]
21,782,422✔
996
        count += 1
21,782,416✔
997
    end
35,542,462✔
998
    return A
9,406,784✔
999
end
1000

1001
# Faster contiguous setindex! with copyto!
1002
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
109✔
1003
    @inline
1,008,710✔
1004
    @boundscheck checkbounds(A, I)
1,008,942✔
1005
    lI = length(I)
1,008,942✔
1006
    @boundscheck setindex_shape_check(X, lI)
1,008,942✔
1007
    if lI > 0
1,008,942✔
1008
        unsafe_copyto!(A, first(I), X, 1, lI)
2,017,468✔
1009
    end
1010
    return A
1,008,942✔
1011
end
1012
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
40✔
1013
    @inline
74✔
1014
    lI = length(A)
74✔
1015
    @boundscheck setindex_shape_check(X, lI)
74✔
1016
    if lI > 0
74✔
1017
        unsafe_copyto!(A, 1, X, 1, lI)
148✔
1018
    end
1019
    return A
74✔
1020
end
1021

1022
# Pick new memory size for efficiently growing an array
1023
# TODO: This should know about the size of our GC pools
1024
# Specifically we are wasting ~10% of memory for small arrays
1025
# by not picking memory sizes that max out a GC pool
1026
function overallocation(maxsize)
1027
    maxsize < 8 && return 8;
1,245,097,574✔
1028
    # compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
1029
    # for small n, we grow faster than O(n)
1030
    # for large n, we grow at O(n/8)
1031
    # and as we reach O(memory) for memory>>1MB,
1032
    # this means we end by adding about 10% of memory each time
1033
    exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
89,610,324✔
1034
    maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8)
89,610,324✔
1035
    return maxsize
89,610,324✔
1036
end
1037

1038
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
2,147,483,647✔
1039

1040
function _growbeg!(a::Vector, delta::Integer)
38✔
1041
    @_noub_meta
19,581✔
1042
    delta = Int(delta)
19,581✔
1043
    delta == 0 && return # avoid attempting to index off the end
24,391,322✔
1044
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
24,390,750✔
1045
    ref = a.ref
73,604,068✔
1046
    mem = ref.mem
73,604,068✔
1047
    len = length(a)
73,604,068✔
1048
    offset = memoryrefoffset(ref)
73,604,068✔
1049
    newlen = len + delta
73,604,068✔
1050
    setfield!(a, :size, (newlen,))
73,604,068✔
1051
    # if offset is far enough advanced to fit data in existing memory without copying
1052
    if delta <= offset - 1
73,604,068✔
1053
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
48,254,614✔
1054
    else
1055
        @noinline (function()
50,699,139✔
1056
        memlen = length(mem)
25,349,686✔
1057
        if offset + len - 1 > memlen || offset < 1
50,699,372✔
1058
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1059
        end
1060
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1061
        # the +1 is because I didn't want to have an off by 1 error.
1062
        newmemlen = max(overallocation(memlen), len + 2 * delta + 1)
38,819,437✔
1063
        newoffset = div(newmemlen - newlen, 2) + 1
25,349,686✔
1064
        # If there is extra data after the end of the array we can use that space so long as there is enough
1065
        # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1066
        # Specifically, we want to ensure that we will only do this operation once before
1067
        # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1068
        if newoffset + newlen < memlen
25,349,686✔
1069
            newoffset = div(memlen - newlen, 2) + 1
×
1070
            newmem = mem
×
1071
        else
1072
            newmem = array_new_memory(mem, newmemlen)
25,349,686✔
1073
        end
1074
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
50,685,000✔
1075
        if ref !== a.ref
25,349,686✔
1076
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1077
        end
1078
        setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
25,349,686✔
1079
        end)()
1080
    end
1081
    return
73,604,068✔
1082
end
1083

1084
function _growend!(a::Vector, delta::Integer)
28✔
1085
    @_noub_meta
7,790,315✔
1086
    delta = Int(delta)
7,809,315✔
1087
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,247,408,979✔
1088
    ref = a.ref
2,147,483,647✔
1089
    mem = ref.mem
2,147,483,647✔
1090
    memlen = length(mem)
2,147,483,647✔
1091
    len = length(a)
2,147,483,647✔
1092
    newlen = len + delta
2,147,483,647✔
1093
    offset = memoryrefoffset(ref)
2,147,483,647✔
1094
    setfield!(a, :size, (newlen,))
2,147,483,647✔
1095
    newmemlen = offset + newlen - 1
2,147,483,647✔
1096
    if memlen < newmemlen
2,147,483,647✔
1097
        @noinline (function()
2,147,483,647✔
1098
        if offset + len - 1 > memlen || offset < 1
2,147,483,647✔
1099
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1100
        end
1101

1102
        if offset - 1 > div(5 * newlen, 4)
1,198,202,832✔
1103
            # If the offset is far enough that we can copy without resizing
1104
            # while maintaining proportional spacing on both ends of the array
1105
            # note that this branch prevents infinite growth when doing combinations
1106
            # of push! and popfirst! (i.e. when using a Vector as a queue)
1107
            newmem = mem
23,578✔
1108
            newoffset = div(newlen, 8) + 1
23,578✔
1109
        else
1110
            # grow either by our computed overallocation factor
1111
            # or exactly the requested size, whichever is larger
1112
            # TODO we should possibly increase the offset if the current offset is nonzero.
1113
            newmemlen2 = max(overallocation(memlen), newmemlen)
1,266,142,863✔
1114
            newmem = array_new_memory(mem, newmemlen2)
2,147,483,647✔
1115
            newoffset = offset
1,198,179,254✔
1116
        end
1117
        newref = @inbounds memoryref(newmem, newoffset)
1,198,202,832✔
1118
        unsafe_copyto!(newref, ref, len)
1,307,405,424✔
1119
        if ref !== a.ref
1,198,202,831✔
1120
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1121
        end
1122
        setfield!(a, :ref, newref)
1,198,202,832✔
1123
        end)()
1124
    end
1125
    return
2,147,483,647✔
1126
end
1127

1128
function _growat!(a::Vector, i::Integer, delta::Integer)
108,177,690✔
1129
    @_terminates_globally_noub_meta
307,318✔
1130
    delta = Int(delta)
307,318✔
1131
    i = Int(i)
307,318✔
1132
    i == 1 && return _growbeg!(a, delta)
108,177,690✔
1133
    len = length(a)
84,238,747✔
1134
    i == len + 1 && return _growend!(a, delta)
84,238,747✔
1135
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
83,137,910✔
1136
    1 < i <= len || throw(BoundsError(a, i))
83,137,912✔
1137
    ref = a.ref
83,137,908✔
1138
    mem = ref.mem
83,137,908✔
1139
    memlen = length(mem)
83,137,908✔
1140
    newlen = len + delta
83,137,908✔
1141
    offset = memoryrefoffset(ref)
83,137,908✔
1142
    setfield!(a, :size, (newlen,))
83,137,908✔
1143
    newmemlen = offset + newlen - 1
83,137,908✔
1144

1145
    # which side would we rather grow into?
1146
    prefer_start = i <= div(len, 2)
83,137,908✔
1147
    # if offset is far enough advanced to fit data in beginning of the memory
1148
    if prefer_start && delta <= offset - 1
83,137,908✔
1149
        newref = @inbounds memoryref(mem, offset - delta)
34,083,856✔
1150
        unsafe_copyto!(newref, ref, i)
68,167,712✔
1151
        setfield!(a, :ref, newref)
34,083,856✔
1152
        for j in i:i+delta-1
34,083,856✔
1153
            @inbounds _unsetindex!(a, j)
48,072,885✔
1154
        end
48,066,064✔
1155
    elseif !prefer_start && memlen >= newmemlen
49,054,052✔
1156
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
70,931,406✔
1157
        for j in i:i+delta-1
35,465,703✔
1158
            @inbounds _unsetindex!(a, j)
49,208,730✔
1159
        end
49,199,413✔
1160
    else
1161
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1162
        # the +1 is because I didn't want to have an off by 1 error.
1163
        newmemlen = max(overallocation(memlen), len+2*delta+1)
19,772,737✔
1164
        newoffset = (newmemlen - newlen) ÷ 2 + 1
13,588,349✔
1165
        newmem = array_new_memory(mem, newmemlen)
27,176,698✔
1166
        newref = @inbounds memoryref(newmem, newoffset)
13,588,349✔
1167
        unsafe_copyto!(newref, ref, i-1)
27,176,698✔
1168
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
27,176,698✔
1169
        setfield!(a, :ref, newref)
13,588,349✔
1170
    end
1171
end
1172

1173
# efficiently delete part of an array
1174
function _deletebeg!(a::Vector, delta::Integer)
21,147,376✔
1175
    delta = Int(delta)
1,083,352✔
1176
    len = length(a)
76,309,468✔
1177
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
76,309,468✔
1178
    for i in 1:delta
22,332,230✔
1179
        @inbounds _unsetindex!(a, i)
103,482,704✔
1180
    end
34,305,178✔
1181
    newlen = len - delta
76,309,468✔
1182
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
76,309,468✔
1183
        newref = @inbounds memoryref(a.ref, delta + 1)
69,392,597✔
1184
        setfield!(a, :ref, newref)
69,392,596✔
1185
    end
1186
    setfield!(a, :size, (newlen,))
76,309,468✔
1187
    return
76,309,468✔
1188
end
1189
function _deleteend!(a::Vector, delta::Integer)
22,989,847✔
1190
    delta = Int(delta)
6,261,024✔
1191
    len = length(a)
1,514,128,404✔
1192
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
1,514,128,404✔
1193
    newlen = len - delta
1,514,128,404✔
1194
    for i in newlen+1:len
1,551,775,639✔
1195
        @inbounds _unsetindex!(a, i)
2,147,483,647✔
1196
    end
2,147,483,647✔
1197
    setfield!(a, :size, (newlen,))
1,514,128,404✔
1198
    return
1,514,128,404✔
1199
end
1200
function _deleteat!(a::Vector, i::Integer, delta::Integer)
7,670,618✔
1201
    i = Int(i)
102,012✔
1202
    len = length(a)
7,670,618✔
1203
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
7,670,618✔
1204
    1 <= i <= len || throw(BoundsError(a, i))
7,670,621✔
1205
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
7,670,615✔
1206
    newa = a
101,997✔
1207
    if 2*i + delta <= len
7,670,615✔
1208
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
170,859✔
1209
        _deletebeg!(a, delta)
3,539,895✔
1210
    else
1211
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
10,144,973✔
1212
        _deleteend!(a, delta)
7,546,722✔
1213
    end
1214
    return
7,670,615✔
1215
end
1216
## Dequeue functionality ##
1217

1218
"""
1219
    push!(collection, items...) -> collection
1220

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

1224
# Examples
1225
```jldoctest
1226
julia> push!([1, 2, 3], 4, 5, 6)
1227
6-element Vector{Int64}:
1228
 1
1229
 2
1230
 3
1231
 4
1232
 5
1233
 6
1234
```
1235

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

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

1242
See also [`pushfirst!`](@ref).
1243
"""
1244
function push! end
1245

1246
function push!(a::Vector{T}, item) where T
56,823✔
1247
    # convert first so we don't grow the array if the assignment won't work
1248
    itemT = item isa T ? item : convert(T, item)::T
42,485,320✔
1249
    _growend!(a, 1)
2,147,483,647✔
1250
    @_safeindex a[length(a)] = itemT
2,147,483,647✔
1251
    return a
2,147,483,647✔
1252
end
1253

1254
# specialize and optimize the single argument case
1255
function push!(a::Vector{Any}, @nospecialize x)
8,075✔
1256
    _growend!(a, 1)
129,889,961✔
1257
    @_safeindex a[length(a)] = x
129,889,961✔
1258
    return a
129,889,961✔
1259
end
1260
function push!(a::Vector{Any}, @nospecialize x...)
16✔
1261
    @_terminates_locally_meta
17✔
1262
    na = length(a)
227,269✔
1263
    nx = length(x)
17✔
1264
    _growend!(a, nx)
227,269✔
1265
    @_safeindex for i = 1:nx
454,521✔
1266
        a[na+i] = x[i]
611,229✔
1267
    end
681,921✔
1268
    return a
227,269✔
1269
end
1270

1271
"""
1272
    append!(collection, collections...) -> collection.
1273

1274
For an ordered container `collection`, add the elements of each `collections`
1275
to the end of it.
1276

1277
!!! compat "Julia 1.6"
1278
    Specifying multiple collections to be appended requires at least Julia 1.6.
1279

1280
# Examples
1281
```jldoctest
1282
julia> append!([1], [2, 3])
1283
3-element Vector{Int64}:
1284
 1
1285
 2
1286
 3
1287

1288
julia> append!([1, 2, 3], [4, 5], [6])
1289
6-element Vector{Int64}:
1290
 1
1291
 2
1292
 3
1293
 4
1294
 5
1295
 6
1296
```
1297

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

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

1304
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1305
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1306
"""
1307
function append! end
1308

1309
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
8,407✔
1310
    items isa Tuple && (items = map(x -> convert(T, x), items))
2,252,534✔
1311
    n = length(items)
82,797,638✔
1312
    _growend!(a, n)
83,320,815✔
1313
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
128,993,545✔
1314
    return a
83,320,815✔
1315
end
1316

1317
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
86,219,229✔
1318
push!(a::AbstractVector, iter...) = append!(a, iter)
1,262,410✔
1319
append!(a::AbstractVector, iter...) = (for v in iter; append!(a, v); end; return a)
7✔
1320

1321
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
26,845,863✔
1322
    n = Int(length(iter))::Int
27,079,618✔
1323
    i = lastindex(a)
30✔
1324
    sizehint!(a, length(a) + n; shrink=false)
26,845,865✔
1325
    for item in iter
43,974,961✔
1326
        push!(a, item)
50,877,633✔
1327
    end
51,109,386✔
1328
    a
11✔
1329
end
1330
function _append!(a::AbstractVector, ::IteratorSize, iter)
59,373,363✔
1331
    for item in iter
71,917,984✔
1332
        push!(a, item)
60,560,378✔
1333
    end
60,560,383✔
1334
    a
3✔
1335
end
1336

1337
"""
1338
    prepend!(a::Vector, collections...) -> collection
1339

1340
Insert the elements of each `collections` to the beginning of `a`.
1341

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

1345
!!! compat "Julia 1.6"
1346
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1347

1348
# Examples
1349
```jldoctest
1350
julia> prepend!([3], [1, 2])
1351
3-element Vector{Int64}:
1352
 1
1353
 2
1354
 3
1355

1356
julia> prepend!([6], [1, 2], [3, 4, 5])
1357
6-element Vector{Int64}:
1358
 1
1359
 2
1360
 3
1361
 4
1362
 5
1363
 6
1364
```
1365
"""
1366
function prepend! end
1367

1368
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
2,154✔
1369
    items isa Tuple && (items = map(x -> convert(T, x), items))
4,928✔
1370
    n = length(items)
7,107✔
1371
    _growbeg!(a, n)
13,641✔
1372
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1373
    # just the last n elements instead of all of them from the first
1374
    copyto!(a, 1, items, lastindex(items)-n+1, n)
13,636✔
1375
    return a
7,107✔
1376
end
1377

1378
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
384✔
1379
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
15✔
1380
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
7✔
1381

1382
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
364✔
1383
    @_terminates_locally_meta
365✔
1384
    require_one_based_indexing(a)
365✔
1385
    n = Int(length(iter))::Int
365✔
1386
    sizehint!(a, length(a) + n; first=true, shrink=false)
365✔
1387
    n = 0
365✔
1388
    for item in iter
366✔
1389
        n += 1
603✔
1390
        pushfirst!(a, item)
603✔
1391
    end
599✔
1392
    reverse!(a, 1, n)
359✔
1393
    a
359✔
1394
end
1395
function _prepend!(a::Vector, ::IteratorSize, iter)
3✔
1396
    n = 0
3✔
1397
    for item in iter
5✔
1398
        n += 1
8✔
1399
        pushfirst!(a, item)
11✔
1400
    end
13✔
1401
    reverse!(a, 1, n)
2✔
1402
    a
2✔
1403
end
1404

1405
"""
1406
    resize!(a::Vector, n::Integer) -> Vector
1407

1408
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1409
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1410
guaranteed to be initialized.
1411

1412
# Examples
1413
```jldoctest
1414
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1415
3-element Vector{Int64}:
1416
 6
1417
 5
1418
 4
1419

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

1422
julia> length(a)
1423
8
1424

1425
julia> a[1:6]
1426
6-element Vector{Int64}:
1427
 6
1428
 5
1429
 4
1430
 3
1431
 2
1432
 1
1433
```
1434
"""
1435
function resize!(a::Vector, nl::Integer)
1,350,559,561✔
1436
    l = length(a)
1,410,835,158✔
1437
    if nl > l
1,410,835,158✔
1438
        _growend!(a, nl-l)
955,337,789✔
1439
    elseif nl != l
455,497,371✔
1440
        if nl < 0
113,665,124✔
1441
            _throw_argerror("new length must be ≥ 0")
2✔
1442
        end
1443
        _deleteend!(a, l-nl)
113,665,122✔
1444
    end
1445
    return a
1,410,835,156✔
1446
end
1447

1448
"""
1449
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1450

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

1456
If `first` is `true`, then any additional space is reserved before the start of the collection.
1457
This way, subsequent calls to `pushfirst!` (instead of `push!`) may become faster.
1458
Supplying this keyword may result in an error if the collection is not ordered
1459
or if `pushfirst!` is not supported for this collection.
1460

1461
If `shrink=true` (the default), the collection's capacity may be reduced if its current
1462
capacity is greater than `n`.
1463

1464
See also [`resize!`](@ref).
1465

1466
# Notes on the performance model
1467

1468
For types that support `sizehint!`,
1469

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

1474
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1475
   `Base`.
1476

1477
3. `empty!` is nearly costless (and O(1)) for types that support this kind of preallocation.
1478

1479
!!! compat "Julia 1.11"
1480
    The `shrink` and `first` arguments were added in Julia 1.11.
1481
"""
1482
function sizehint! end
1483

1484
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
53,953,169✔
1485
    len = length(a)
26,975,813✔
1486
    ref = a.ref
26,975,813✔
1487
    mem = ref.mem
26,975,813✔
1488
    memlen = length(mem)
26,975,813✔
1489
    sz = max(Int(sz), len)
26,975,813✔
1490
    inc = sz - len
26,975,813✔
1491
    if sz <= memlen
26,975,813✔
1492
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1493
        if !shrink || memlen - sz <= div(memlen, 8)
23,474,688✔
1494
            return a
23,263,079✔
1495
        end
1496
        newmem = array_new_memory(mem, sz)
144,130✔
1497
        if first
97,244✔
1498
            newref = memoryref(newmem, inc + 1)
×
1499
        else
1500
            newref = memoryref(newmem)
97,244✔
1501
        end
1502
        unsafe_copyto!(newref, ref, len)
163,212✔
1503
        setfield!(a, :ref, newref)
97,244✔
1504
    elseif first
3,615,490✔
1505
        _growbeg!(a, inc)
720✔
1506
        newref = getfield(a, :ref)
360✔
1507
        newref = memoryref(newref, inc + 1)
360✔
1508
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
360✔
1509
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
360✔
1510
    else # last
1511
        _growend!(a, inc)
3,615,130✔
1512
        setfield!(a, :size, (len,)) # undo the size change from _growend!
3,615,130✔
1513
    end
1514
    a
6,766✔
1515
end
1516

1517
# Fall-back implementation for non-shrinkable collections
1518
# avoid defining this the normal way to avoid avoid infinite recursion
1519
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
10✔
1520
    get(kwargs, :first, false)::Bool
211✔
1521
    get(kwargs, :shrink, true)::Bool
211✔
1522
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
211✔
1523
    sizehint!(a, sz)
211✔
1524
end
1525

1526
"""
1527
    pop!(collection) -> item
1528

1529
Remove an item in `collection` and return it. If `collection` is an
1530
ordered container, the last item is returned; for unordered containers,
1531
an arbitrary element is returned.
1532

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

1535
# Examples
1536
```jldoctest
1537
julia> A=[1, 2, 3]
1538
3-element Vector{Int64}:
1539
 1
1540
 2
1541
 3
1542

1543
julia> pop!(A)
1544
3
1545

1546
julia> A
1547
2-element Vector{Int64}:
1548
 1
1549
 2
1550

1551
julia> S = Set([1, 2])
1552
Set{Int64} with 2 elements:
1553
  2
1554
  1
1555

1556
julia> pop!(S)
1557
2
1558

1559
julia> S
1560
Set{Int64} with 1 element:
1561
  1
1562

1563
julia> pop!(Dict(1=>2))
1564
1 => 2
1565
```
1566
"""
1567
function pop!(a::Vector)
21,287✔
1568
    if isempty(a)
1,309,786,656✔
1569
        _throw_argerror("array must be non-empty")
1✔
1570
    end
1571
    item = a[end]
1,309,786,655✔
1572
    _deleteend!(a, 1)
1,309,786,655✔
1573
    return item
1,309,786,655✔
1574
end
1575

1576
"""
1577
    popat!(a::Vector, i::Integer, [default])
1578

1579
Remove the item at the given `i` and return it. Subsequent items
1580
are shifted to fill the resulting gap.
1581
When `i` is not a valid index for `a`, return `default`, or throw an error if
1582
`default` is not specified.
1583

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

1586
!!! compat "Julia 1.5"
1587
    This function is available as of Julia 1.5.
1588

1589
# Examples
1590
```jldoctest
1591
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1592
3
1593

1594
julia> a
1595
3-element Vector{Int64}:
1596
 4
1597
 2
1598
 1
1599

1600
julia> popat!(a, 4, missing)
1601
missing
1602

1603
julia> popat!(a, 4)
1604
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1605
[...]
1606
```
1607
"""
1608
function popat!(a::Vector, i::Integer)
4✔
1609
    x = a[i]
10✔
1610
    _deleteat!(a, i, 1)
4✔
1611
    x
4✔
1612
end
1613

1614
function popat!(a::Vector, i::Integer, default)
2✔
1615
    if 1 <= i <= length(a)
2✔
1616
        x = @inbounds a[i]
1✔
1617
        _deleteat!(a, i, 1)
1✔
1618
        x
1✔
1619
    else
1620
        default
1✔
1621
    end
1622
end
1623

1624
"""
1625
    pushfirst!(collection, items...) -> collection
1626

1627
Insert one or more `items` at the beginning of `collection`.
1628

1629
This function is called `unshift` in many other programming languages.
1630

1631
# Examples
1632
```jldoctest
1633
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1634
6-element Vector{Int64}:
1635
 5
1636
 6
1637
 1
1638
 2
1639
 3
1640
 4
1641
```
1642
"""
1643
function pushfirst!(a::Vector{T}, item) where T
410✔
1644
    item = item isa T ? item : convert(T, item)::T
2,865✔
1645
    _growbeg!(a, 1)
37,723✔
1646
    @_safeindex a[1] = item
35,919✔
1647
    return a
35,919✔
1648
end
1649

1650
# specialize and optimize the single argument case
1651
function pushfirst!(a::Vector{Any}, @nospecialize x)
12✔
1652
    _growbeg!(a, 1)
50,219,429✔
1653
    @_safeindex a[1] = x
49,178,806✔
1654
    return a
49,178,806✔
1655
end
1656
function pushfirst!(a::Vector{Any}, @nospecialize x...)
1✔
1657
    @_terminates_locally_meta
2✔
1658
    na = length(a)
2✔
1659
    nx = length(x)
2✔
1660
    _growbeg!(a, nx)
1,416✔
1661
    @_safeindex for i = 1:nx
1,414✔
1662
        a[i] = x[i]
1,418✔
1663
    end
2,128✔
1664
    return a
708✔
1665
end
1666

1667
"""
1668
    popfirst!(collection) -> item
1669

1670
Remove the first `item` from `collection`.
1671

1672
This function is called `shift` in many other programming languages.
1673

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

1676
# Examples
1677
```jldoctest
1678
julia> A = [1, 2, 3, 4, 5, 6]
1679
6-element Vector{Int64}:
1680
 1
1681
 2
1682
 3
1683
 4
1684
 5
1685
 6
1686

1687
julia> popfirst!(A)
1688
1
1689

1690
julia> A
1691
5-element Vector{Int64}:
1692
 2
1693
 3
1694
 4
1695
 5
1696
 6
1697
```
1698
"""
1699
function popfirst!(a::Vector)
321✔
1700
    if isempty(a)
76,158,206✔
1701
        _throw_argerror("array must be non-empty")
1✔
1702
    end
1703
    item = a[1]
76,158,204✔
1704
    _deletebeg!(a, 1)
76,158,205✔
1705
    return item
76,158,205✔
1706
end
1707

1708
"""
1709
    insert!(a::Vector, index::Integer, item)
1710

1711
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1712
the resulting `a`.
1713

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

1716
# Examples
1717
```jldoctest
1718
julia> insert!(Any[1:6;], 3, "here")
1719
7-element Vector{Any}:
1720
 1
1721
 2
1722
  "here"
1723
 3
1724
 4
1725
 5
1726
 6
1727
```
1728
"""
1729
function insert!(a::Array{T,1}, i::Integer, item) where T
310✔
1730
    @_noub_meta
1,329,014✔
1731
    # Throw convert error before changing the shape of the array
1732
    _item = item isa T ? item : convert(T, item)::T
1,329,054✔
1733
    _growat!(a, i, 1)
86,802,882✔
1734
    # :noub, because _growat! already did bound check
1735
    @inbounds a[i] = _item
86,802,880✔
1736
    return a
86,802,880✔
1737
end
1738

1739
"""
1740
    deleteat!(a::Vector, i::Integer)
1741

1742
Remove the item at the given `i` and return the modified `a`. Subsequent items
1743
are shifted to fill the resulting gap.
1744

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

1747
# Examples
1748
```jldoctest
1749
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1750
5-element Vector{Int64}:
1751
 6
1752
 4
1753
 3
1754
 2
1755
 1
1756
```
1757
"""
1758
function deleteat!(a::Vector, i::Integer)
404✔
1759
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,833✔
1760
    _deleteat!(a, i, 1)
7,468,227✔
1761
    return a
16,831✔
1762
end
1763

1764
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
34,081✔
1765
    if eltype(r) === Bool
75,698✔
1766
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1767
    else
1768
        n = length(a)
75,692✔
1769
        f = first(r)
75,692✔
1770
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
75,692✔
1771
        isempty(r) || _deleteat!(a, f, length(r))
381,974✔
1772
        return a
192,809✔
1773
    end
1774
end
1775

1776
"""
1777
    deleteat!(a::Vector, inds)
1778

1779
Remove the items at the indices given by `inds`, and return the modified `a`.
1780
Subsequent items are shifted to fill the resulting gap.
1781

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

1785
# Examples
1786
```jldoctest
1787
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1788
3-element Vector{Int64}:
1789
 5
1790
 3
1791
 1
1792

1793
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1794
3-element Vector{Int64}:
1795
 5
1796
 3
1797
 1
1798

1799
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1800
ERROR: ArgumentError: indices must be unique and sorted
1801
Stacktrace:
1802
[...]
1803
```
1804
"""
1805
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1806
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
111,037✔
1807

1808
struct Nowhere; end
1809
push!(::Nowhere, _) = nothing
×
1810
_growend!(::Nowhere, _) = nothing
×
1811

1812
function _push_deleted!(dltd, a::Vector, ind)
1813
    @_propagate_inbounds_meta
1,491,889✔
1814
    if isassigned(a, ind)
1,573,935✔
1815
        push!(dltd, a[ind])
1,573,934✔
1816
    else
1817
        _growend!(dltd, 1)
×
1818
    end
1819
end
1820

1821
function _copy_item!(a::Vector, p, q)
1822
    @_propagate_inbounds_meta
4,375,265✔
1823
    if isassigned(a, q)
4,417,728✔
1824
        a[p] = a[q]
4,417,727✔
1825
    else
1826
        _unsetindex!(a, p)
1✔
1827
    end
1828
end
1829

1830
function _deleteat!(a::Vector, inds, dltd=Nowhere())
111,057✔
1831
    n = length(a)
222,113✔
1832
    y = iterate(inds)
111,067✔
1833
    y === nothing && return a
111,057✔
1834
    (p, s) = y
35,454✔
1835
    checkbounds(a, p)
110,808✔
1836
    @inbounds _push_deleted!(dltd, a, p)
110,796✔
1837
    q = p+1
110,796✔
1838
    while true
1,573,935✔
1839
        y = iterate(inds, s)
1,573,946✔
1840
        y === nothing && break
1,573,935✔
1841
        (i,s) = y
1,456,441✔
1842
        if !(q <= i <= n)
1,463,141✔
1843
            if i < q
2✔
1844
                _throw_argerror("indices must be unique and sorted")
1✔
1845
            else
1846
                throw(BoundsError())
1✔
1847
            end
1848
        end
1849
        while q < i
2,888,727✔
1850
            @inbounds _copy_item!(a, p, q)
1,425,588✔
1851
            p += 1; q += 1
1,425,588✔
1852
        end
1,425,588✔
1853
        @inbounds _push_deleted!(dltd, a, i)
1,463,139✔
1854
        q = i+1
1,463,139✔
1855
    end
1,463,139✔
1856
    while q <= n
3,060,740✔
1857
        @inbounds _copy_item!(a, p, q)
2,949,946✔
1858
        p += 1; q += 1
2,949,946✔
1859
    end
2,949,946✔
1860
    _deleteend!(a, n-p+1)
1,573,933✔
1861
    return a
110,794✔
1862
end
1863

1864
# Simpler and more efficient version for logical indexing
1865
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1866
    n = length(a)
4,029✔
1867
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1868
    p = 1
4,024✔
1869
    for (q, i) in enumerate(inds)
8,047✔
1870
        @inbounds _copy_item!(a, p, q)
42,194✔
1871
        p += !i
42,194✔
1872
    end
80,365✔
1873
    _deleteend!(a, n-p+1)
21,353✔
1874
    return a
4,024✔
1875
end
1876

1877
const _default_splice = []
1878

1879
"""
1880
    splice!(a::Vector, index::Integer, [replacement]) -> item
1881

1882
Remove the item at the given index, and return the removed item.
1883
Subsequent items are shifted left to fill the resulting gap.
1884
If specified, replacement values from an ordered
1885
collection will be spliced in place of the removed item.
1886

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

1889
# Examples
1890
```jldoctest
1891
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1892
2
1893

1894
julia> A
1895
5-element Vector{Int64}:
1896
 6
1897
 5
1898
 4
1899
 3
1900
 1
1901

1902
julia> splice!(A, 5, -1)
1903
1
1904

1905
julia> A
1906
5-element Vector{Int64}:
1907
  6
1908
  5
1909
  4
1910
  3
1911
 -1
1912

1913
julia> splice!(A, 1, [-1, -2, -3])
1914
6
1915

1916
julia> A
1917
7-element Vector{Int64}:
1918
 -1
1919
 -2
1920
 -3
1921
  5
1922
  4
1923
  3
1924
 -1
1925
```
1926

1927
To insert `replacement` before an index `n` without removing any items, use
1928
`splice!(collection, n:n-1, replacement)`.
1929
"""
1930
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,695✔
1931
    v = a[i]
3,712✔
1932
    m = length(ins)
3,426✔
1933
    if m == 0
3,426✔
1934
        _deleteat!(a, i, 1)
551✔
1935
    elseif m == 1
2,875✔
1936
        a[i] = only(ins)
266✔
1937
    else
1938
        _growat!(a, i, m-1)
2,609✔
1939
        k = 1
2,609✔
1940
        for x in ins
2,609✔
1941
            a[i+k-1] = x
332,674✔
1942
            k += 1
332,674✔
1943
        end
332,674✔
1944
    end
1945
    return v
3,426✔
1946
end
1947

1948
"""
1949
    splice!(a::Vector, indices, [replacement]) -> items
1950

1951
Remove items at specified indices, and return a collection containing
1952
the removed items.
1953
Subsequent items are shifted left to fill the resulting gaps.
1954
If specified, replacement values from an ordered collection will be spliced in
1955
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
1956

1957
To insert `replacement` before an index `n` without removing any items, use
1958
`splice!(collection, n:n-1, replacement)`.
1959

1960
$(_DOCS_ALIASING_WARNING)
1961

1962
!!! compat "Julia 1.5"
1963
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1964

1965
!!! compat "Julia 1.8"
1966
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1967

1968
# Examples
1969
```jldoctest
1970
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
1971
Int64[]
1972

1973
julia> A
1974
8-element Vector{Int64}:
1975
 -1
1976
 -2
1977
 -3
1978
  2
1979
  5
1980
  4
1981
  3
1982
 -1
1983
```
1984
"""
1985
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
21,455,892✔
1986
    v = a[r]
21,526,122✔
1987
    m = length(ins)
71,650✔
1988
    if m == 0
71,650✔
1989
        deleteat!(a, r)
74,059✔
1990
        return v
37,090✔
1991
    end
1992

1993
    n = length(a)
21,384,864✔
1994
    f = first(r)
21,384,864✔
1995
    l = last(r)
21,384,864✔
1996
    d = length(r)
21,384,864✔
1997

1998
    if m < d
21,384,864✔
1999
        delta = d - m
12,573✔
2000
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
18,951✔
2001
    elseif m > d
21,372,291✔
2002
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
21,372,179✔
2003
    end
2004

2005
    k = 1
34,560✔
2006
    for x in ins
21,396,370✔
2007
        a[f+k-1] = x
69,449,317✔
2008
        k += 1
68,099,212✔
2009
    end
90,798,912✔
2010
    return v
21,384,864✔
2011
end
2012

2013
splice!(a::Vector, inds) = (dltds = eltype(a)[]; _deleteat!(a, inds, dltds); dltds)
1✔
2014

2015
function empty!(a::Vector)
56✔
2016
    _deleteend!(a, length(a))
95,991,319✔
2017
    return a
82,951,888✔
2018
end
2019

2020
# use memcmp for cmp on byte arrays
2021
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
2022
    aref = a.ref
3✔
2023
    bref = b.ref
3✔
2024
    ta = @_gc_preserve_begin aref
3✔
2025
    tb = @_gc_preserve_begin bref
3✔
2026
    pa = unsafe_convert(Ptr{Cvoid}, aref)
3✔
2027
    pb = unsafe_convert(Ptr{Cvoid}, bref)
3✔
2028
    c = memcmp(pa, pb, min(length(a),length(b)))
3✔
2029
    @_gc_preserve_end ta
3✔
2030
    @_gc_preserve_end tb
3✔
2031
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
2032
end
2033

2034
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2035
# use memcmp for == on bit integer types
2036
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,478✔
2037
    if size(a) == size(b)
3,599✔
2038
        aref = a.ref
1,830✔
2039
        bref = b.ref
1,830✔
2040
        ta = @_gc_preserve_begin aref
1,830✔
2041
        tb = @_gc_preserve_begin bref
1,830✔
2042
        pa = unsafe_convert(Ptr{Cvoid}, aref)
1,830✔
2043
        pb = unsafe_convert(Ptr{Cvoid}, bref)
1,830✔
2044
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
1,830✔
2045
        @_gc_preserve_end ta
1,830✔
2046
        @_gc_preserve_end tb
1,830✔
2047
        return c == 0
1,830✔
2048
    else
2049
        return false
×
2050
    end
2051
end
2052

2053
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
5,548✔
2054
    len = length(a)
65,190✔
2055
    if len == length(b)
65,190✔
2056
        aref = a.ref
65,066✔
2057
        bref = b.ref
32,157✔
2058
        ta = @_gc_preserve_begin aref
65,066✔
2059
        tb = @_gc_preserve_begin bref
65,066✔
2060
        T = eltype(Arr)
13,776✔
2061
        pa = unsafe_convert(Ptr{T}, aref)
65,066✔
2062
        pb = unsafe_convert(Ptr{T}, bref)
65,066✔
2063
        c = memcmp(pa, pb, sizeof(T) * len)
65,066✔
2064
        @_gc_preserve_end ta
65,066✔
2065
        @_gc_preserve_end tb
65,066✔
2066
        return c == 0
65,066✔
2067
    else
2068
        return false
124✔
2069
    end
2070
end
2071

2072
"""
2073
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2074

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

2078
# Examples
2079
```jldoctest
2080
julia> A = Vector(1:5)
2081
5-element Vector{Int64}:
2082
 1
2083
 2
2084
 3
2085
 4
2086
 5
2087

2088
julia> reverse(A)
2089
5-element Vector{Int64}:
2090
 5
2091
 4
2092
 3
2093
 2
2094
 1
2095

2096
julia> reverse(A, 1, 4)
2097
5-element Vector{Int64}:
2098
 4
2099
 3
2100
 2
2101
 1
2102
 5
2103

2104
julia> reverse(A, 3, 5)
2105
5-element Vector{Int64}:
2106
 1
2107
 2
2108
 5
2109
 4
2110
 3
2111
```
2112
"""
2113
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
9,248✔
2114
    s, n = Int(start), Int(stop)
949✔
2115
    B = similar(A)
18,223✔
2116
    for i = firstindex(A):s-1
9,249✔
2117
        B[i] = A[i]
1,684✔
2118
    end
3,078✔
2119
    for i = s:n
9,261✔
2120
        B[i] = A[n+s-i]
291,209✔
2121
    end
573,183✔
2122
    for i = n+1:lastindex(A)
18,206✔
2123
        B[i] = A[i]
1,690✔
2124
    end
3,090✔
2125
    return B
9,248✔
2126
end
2127

2128
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2129
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2130
    @eval begin
2131
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
161,892,528✔
2132
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
13,261✔
2133
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2134
        function $_f(A::AbstractVector, dim::Integer)
2135
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
2136
            return $_f(A, :)
4✔
2137
        end
2138
    end
2139
end
2140

2141
function reverseind(a::AbstractVector, i::Integer)
3✔
2142
    li = LinearIndices(a)
3✔
2143
    first(li) + last(li) - i
3✔
2144
end
2145

2146
# This implementation of `midpoint` is performance-optimized but safe
2147
# only if `lo <= hi`.
2148
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
17,802,952✔
2149
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2150

2151
"""
2152
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2153

2154
In-place version of [`reverse`](@ref).
2155

2156
# Examples
2157
```jldoctest
2158
julia> A = Vector(1:5)
2159
5-element Vector{Int64}:
2160
 1
2161
 2
2162
 3
2163
 4
2164
 5
2165

2166
julia> reverse!(A);
2167

2168
julia> A
2169
5-element Vector{Int64}:
2170
 5
2171
 4
2172
 3
2173
 2
2174
 1
2175
```
2176
"""
2177
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
237,686✔
2178
    s, n = Int(start), Int(stop)
196,655✔
2179
    if n > s # non-empty and non-trivial
237,683✔
2180
        liv = LinearIndices(v)
225,915✔
2181
        if !(first(liv) ≤ s ≤ last(liv))
225,915✔
2182
            throw(BoundsError(v, s))
3✔
2183
        elseif !(first(liv) ≤ n ≤ last(liv))
225,912✔
2184
            throw(BoundsError(v, n))
1✔
2185
        end
2186
        r = n
186,801✔
2187
        @inbounds for i in s:midpoint(s, n-1)
225,911✔
2188
            v[i], v[r] = v[r], v[i]
10,127,358✔
2189
            r -= 1
10,127,358✔
2190
        end
20,028,805✔
2191
    end
2192
    return v
237,679✔
2193
end
2194

2195
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2196

2197
vcat() = Vector{Any}()
9,912✔
2198
hcat() = Vector{Any}()
1✔
2199

2200
function hcat(V::Vector{T}...) where T
62✔
2201
    height = length(V[1])
570✔
2202
    for j = 2:length(V)
570✔
2203
        if length(V[j]) != height
636✔
2204
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2205
        end
2206
    end
733✔
2207
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
569✔
2208
end
2209
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2210

2211
function vcat(arrays::Vector{T}...) where T
31,885✔
2212
    n = 0
3,808✔
2213
    for a in arrays
31,885✔
2214
        n += length(a)
2,064,209✔
2215
    end
2,096,089✔
2216
    arr = Vector{T}(undef, n)
63,748✔
2217
    nd = 1
3,808✔
2218
    for a in arrays
31,885✔
2219
        na = length(a)
2,064,209✔
2220
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,064,209✔
2221
        unsafe_copyto!(arr, nd, a, 1, na)
4,124,754✔
2222
        nd += na
2,064,209✔
2223
    end
2,096,089✔
2224
    return arr
31,885✔
2225
end
2226
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
35✔
2227

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

2230
## find ##
2231

2232
"""
2233
    findnext(A, i)
2234

2235
Find the next index after or including `i` of a `true` element of `A`,
2236
or `nothing` if not found.
2237

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

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

2250
julia> findnext(A, 1)
2251
3
2252

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

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

2260
julia> findnext(A, CartesianIndex(1, 1))
2261
CartesianIndex(2, 1)
2262
```
2263
"""
2264
findnext(A, start) = findnext(identity, A, start)
43,232✔
2265

2266
"""
2267
    findfirst(A)
2268

2269
Return the index or key of the first `true` value in `A`.
2270
Return `nothing` if no such value is found.
2271
To search for other kinds of values, pass a predicate as the first argument.
2272

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

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

2278
# Examples
2279
```jldoctest
2280
julia> A = [false, false, true, false]
2281
4-element Vector{Bool}:
2282
 0
2283
 0
2284
 1
2285
 0
2286

2287
julia> findfirst(A)
2288
3
2289

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

2292
julia> A = [false false; true false]
2293
2×2 Matrix{Bool}:
2294
 0  0
2295
 1  0
2296

2297
julia> findfirst(A)
2298
CartesianIndex(2, 1)
2299
```
2300
"""
2301
findfirst(A) = findfirst(identity, A)
2✔
2302

2303
# Needed for bootstrap, and allows defining only an optimized findnext method
2304
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
11,976✔
2305

2306
"""
2307
    findnext(predicate::Function, A, i)
2308

2309
Find the next index after or including `i` of an element of `A`
2310
for which `predicate` returns `true`, or `nothing` if not found. This works for
2311
Arrays, Strings, and most other collections that support [`getindex`](@ref),
2312
[`keys(A)`](@ref), and [`nextind`](@ref).
2313

2314
Indices are of the same type as those returned by [`keys(A)`](@ref)
2315
and [`pairs(A)`](@ref).
2316

2317
# Examples
2318
```jldoctest
2319
julia> A = [1, 4, 2, 2];
2320

2321
julia> findnext(isodd, A, 1)
2322
1
2323

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

2326
julia> A = [1 4; 2 2];
2327

2328
julia> findnext(isodd, A, CartesianIndex(1, 1))
2329
CartesianIndex(1, 1)
2330

2331
julia> findnext(isspace, "a b c", 3)
2332
4
2333
```
2334
"""
2335
function findnext(testf::Function, A, start)
19,543✔
2336
    i = oftype(first(keys(A)), start)
45,150✔
2337
    l = last(keys(A))
86,162,808✔
2338
    i > l && return nothing
86,162,808✔
2339
    while true
179,742,497✔
2340
        testf(A[i]) && return i
179,763,323✔
2341
        i == l && break
172,220,525✔
2342
        # nextind(A, l) can throw/overflow
2343
        i = nextind(A, i)
167,312,106✔
2344
    end
167,312,087✔
2345
    return nothing
4,908,414✔
2346
end
2347

2348
"""
2349
    findfirst(predicate::Function, A)
2350

2351
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2352
Return `nothing` if there is no such element.
2353

2354
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2355
and [`pairs(A)`](@ref).
2356

2357
# Examples
2358
```jldoctest
2359
julia> A = [1, 4, 2, 2]
2360
4-element Vector{Int64}:
2361
 1
2362
 4
2363
 2
2364
 2
2365

2366
julia> findfirst(iseven, A)
2367
2
2368

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

2371
julia> findfirst(isequal(4), A)
2372
2
2373

2374
julia> A = [1 4; 2 2]
2375
2×2 Matrix{Int64}:
2376
 1  4
2377
 2  2
2378

2379
julia> findfirst(iseven, A)
2380
CartesianIndex(2, 1)
2381
```
2382
"""
2383
function findfirst(testf::Function, A)
15✔
2384
    for (i, a) in pairs(A)
22✔
2385
        testf(a) && return i
14✔
2386
    end
11✔
2387
    return nothing
8✔
2388
end
2389

2390
# Needed for bootstrap, and allows defining only an optimized findnext method
2391
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
267,046,667✔
2392
    findnext(testf, A, first(keys(A)))
2393

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

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

2400
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2401
    isempty(r) && return nothing
6✔
2402
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2403
    d = convert(S, p.x - first(r))::S
3✔
2404
    iszero(d % step(r)) || return nothing
3✔
2405
    return d ÷ step(r) + 1
3✔
2406
end
2407

2408
"""
2409
    findprev(A, i)
2410

2411
Find the previous index before or including `i` of a `true` element of `A`,
2412
or `nothing` if not found.
2413

2414
Indices are of the same type as those returned by [`keys(A)`](@ref)
2415
and [`pairs(A)`](@ref).
2416

2417
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2418

2419
# Examples
2420
```jldoctest
2421
julia> A = [false, false, true, true]
2422
4-element Vector{Bool}:
2423
 0
2424
 0
2425
 1
2426
 1
2427

2428
julia> findprev(A, 3)
2429
3
2430

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

2433
julia> A = [false false; true true]
2434
2×2 Matrix{Bool}:
2435
 0  0
2436
 1  1
2437

2438
julia> findprev(A, CartesianIndex(2, 1))
2439
CartesianIndex(2, 1)
2440
```
2441
"""
2442
findprev(A, start) = findprev(identity, A, start)
8,326✔
2443

2444
"""
2445
    findlast(A)
2446

2447
Return the index or key of the last `true` value in `A`.
2448
Return `nothing` if there is no `true` value in `A`.
2449

2450
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2451
and [`pairs(A)`](@ref).
2452

2453
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2454

2455
# Examples
2456
```jldoctest
2457
julia> A = [true, false, true, false]
2458
4-element Vector{Bool}:
2459
 1
2460
 0
2461
 1
2462
 0
2463

2464
julia> findlast(A)
2465
3
2466

2467
julia> A = falses(2,2);
2468

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

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

2476
julia> findlast(A)
2477
CartesianIndex(2, 1)
2478
```
2479
"""
2480
findlast(A) = findlast(identity, A)
23✔
2481

2482
# Needed for bootstrap, and allows defining only an optimized findprev method
2483
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
249✔
2484

2485
"""
2486
    findprev(predicate::Function, A, i)
2487

2488
Find the previous index before or including `i` of an element of `A`
2489
for which `predicate` returns `true`, or `nothing` if not found. This works for
2490
Arrays, Strings, and most other collections that support [`getindex`](@ref),
2491
[`keys(A)`](@ref), and [`nextind`](@ref).
2492

2493
Indices are of the same type as those returned by [`keys(A)`](@ref)
2494
and [`pairs(A)`](@ref).
2495

2496
# Examples
2497
```jldoctest
2498
julia> A = [4, 6, 1, 2]
2499
4-element Vector{Int64}:
2500
 4
2501
 6
2502
 1
2503
 2
2504

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

2507
julia> findprev(isodd, A, 3)
2508
3
2509

2510
julia> A = [4 6; 1 2]
2511
2×2 Matrix{Int64}:
2512
 4  6
2513
 1  2
2514

2515
julia> findprev(isodd, A, CartesianIndex(1, 2))
2516
CartesianIndex(2, 1)
2517

2518
julia> findprev(isspace, "a b c", 3)
2519
2
2520
```
2521
"""
2522
function findprev(testf::Function, A, start)
312✔
2523
    f = first(keys(A))
36,910✔
2524
    i = oftype(f, start)
36,921✔
2525
    i < f && return nothing
38,604✔
2526
    while true
181,574✔
2527
        testf(A[i]) && return i
181,875✔
2528
        i == f && break
143,095✔
2529
        # prevind(A, f) can throw/underflow
2530
        i = prevind(A, i)
142,999✔
2531
    end
142,971✔
2532
    return nothing
93✔
2533
end
2534

2535
"""
2536
    findlast(predicate::Function, A)
2537

2538
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2539
Return `nothing` if there is no such element.
2540

2541
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2542
and [`pairs(A)`](@ref).
2543

2544
# Examples
2545
```jldoctest
2546
julia> A = [1, 2, 3, 4]
2547
4-element Vector{Int64}:
2548
 1
2549
 2
2550
 3
2551
 4
2552

2553
julia> findlast(isodd, A)
2554
3
2555

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

2558
julia> A = [1 2; 3 4]
2559
2×2 Matrix{Int64}:
2560
 1  2
2561
 3  4
2562

2563
julia> findlast(isodd, A)
2564
CartesianIndex(2, 1)
2565
```
2566
"""
2567
function findlast(testf::Function, A)
3✔
2568
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2569
        testf(a) && return i
6✔
2570
    end
6✔
2571
    return nothing
2✔
2572
end
2573

2574
# Needed for bootstrap, and allows defining only an optimized findprev method
2575
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
14,988✔
2576
    findprev(testf, A, last(keys(A)))
2577

2578
"""
2579
    findall(f::Function, A)
2580

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

2584
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2585
and [`pairs(A)`](@ref).
2586

2587
# Examples
2588
```jldoctest
2589
julia> x = [1, 3, 4]
2590
3-element Vector{Int64}:
2591
 1
2592
 3
2593
 4
2594

2595
julia> findall(isodd, x)
2596
2-element Vector{Int64}:
2597
 1
2598
 2
2599

2600
julia> A = [1 2 0; 3 4 0]
2601
2×3 Matrix{Int64}:
2602
 1  2  0
2603
 3  4  0
2604
julia> findall(isodd, A)
2605
2-element Vector{CartesianIndex{2}}:
2606
 CartesianIndex(1, 1)
2607
 CartesianIndex(2, 1)
2608

2609
julia> findall(!iszero, A)
2610
4-element Vector{CartesianIndex{2}}:
2611
 CartesianIndex(1, 1)
2612
 CartesianIndex(2, 1)
2613
 CartesianIndex(1, 2)
2614
 CartesianIndex(2, 2)
2615

2616
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2617
Dict{Symbol, Int64} with 3 entries:
2618
  :A => 10
2619
  :B => -1
2620
  :C => 0
2621

2622
julia> findall(≥(0), d)
2623
2-element Vector{Symbol}:
2624
 :A
2625
 :C
2626

2627
```
2628
"""
2629
function findall(testf::Function, A)
26✔
2630
    gen = (first(p) for p in pairs(A) if testf(last(p)))
59✔
2631
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
59✔
2632
end
2633

2634
# Broadcasting is much faster for small testf, and computing
2635
# integer indices from logical index using findall has a negligible cost
2636
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
247✔
2637

2638
"""
2639
    findall(A)
2640

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

2645
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2646
and [`pairs(A)`](@ref).
2647

2648
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2649

2650
# Examples
2651
```jldoctest
2652
julia> A = [true, false, false, true]
2653
4-element Vector{Bool}:
2654
 1
2655
 0
2656
 0
2657
 1
2658

2659
julia> findall(A)
2660
2-element Vector{Int64}:
2661
 1
2662
 4
2663

2664
julia> A = [true false; false true]
2665
2×2 Matrix{Bool}:
2666
 1  0
2667
 0  1
2668

2669
julia> findall(A)
2670
2-element Vector{CartesianIndex{2}}:
2671
 CartesianIndex(1, 1)
2672
 CartesianIndex(2, 2)
2673

2674
julia> findall(falses(3))
2675
Int64[]
2676
```
2677
"""
2678
function findall(A)
4✔
2679
    collect(first(p) for p in pairs(A) if last(p))
4✔
2680
end
2681

2682
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2683
function findall(A::AbstractArray{Bool})
823✔
2684
    n = count(A)
3,690✔
2685
    I = Vector{eltype(keys(A))}(undef, n)
6,998✔
2686
    cnt = 1
3,685✔
2687
    for (i,a) in pairs(A)
7,362✔
2688
        if a
209,248✔
2689
            I[cnt] = i
129,014✔
2690
            cnt += 1
129,014✔
2691
        end
2692
    end
414,816✔
2693
    I
3,685✔
2694
end
2695

2696
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2697
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2698
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2699

2700
# similar to Matlab's ismember
2701
"""
2702
    indexin(a, b)
2703

2704
Return an array containing the first index in `b` for
2705
each value in `a` that is a member of `b`. The output
2706
array contains `nothing` wherever `a` is not a member of `b`.
2707

2708
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2709

2710
# Examples
2711
```jldoctest
2712
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2713

2714
julia> b = ['a', 'b', 'c'];
2715

2716
julia> indexin(a, b)
2717
6-element Vector{Union{Nothing, Int64}}:
2718
 1
2719
 2
2720
 3
2721
 2
2722
  nothing
2723
 1
2724

2725
julia> indexin(b, a)
2726
3-element Vector{Union{Nothing, Int64}}:
2727
 1
2728
 2
2729
 3
2730
```
2731
"""
2732
function indexin(a, b::AbstractArray)
7✔
2733
    inds = keys(b)
7✔
2734
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2735
    for (val, ind) in zip(b, inds)
14✔
2736
        get!(bdict, val, ind)
30✔
2737
    end
53✔
2738
    return Union{eltype(inds), Nothing}[
7✔
2739
        get(bdict, i, nothing) for i in a
2740
    ]
2741
end
2742

2743
function _findin(a::Union{AbstractArray, Tuple}, b)
375✔
2744
    ind  = Vector{eltype(keys(a))}()
561✔
2745
    bset = Set(b)
377✔
2746
    @inbounds for (i,ai) in pairs(a)
606✔
2747
        ai in bset && push!(ind, i)
90,559✔
2748
    end
180,565✔
2749
    ind
375✔
2750
end
2751

2752
# If two collections are already sorted, _findin can be computed with
2753
# a single traversal of the two collections. This is much faster than
2754
# using a hash table (although it has the same complexity).
2755
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
9✔
2756
    viter, witer = keys(v), eachindex(w)
9✔
2757
    out  = eltype(viter)[]
9✔
2758
    vy, wy = iterate(viter), iterate(witer)
11✔
2759
    if vy === nothing || wy === nothing
17✔
2760
        return out
2✔
2761
    end
2762
    viteri, i = vy
7✔
2763
    witerj, j = wy
7✔
2764
    @inbounds begin
7✔
2765
        vi, wj = v[viteri], w[witerj]
7✔
2766
        while true
54✔
2767
            if isless(vi, wj)
56✔
2768
                vy = iterate(viter, i)
25✔
2769
                if vy === nothing
14✔
2770
                    break
2✔
2771
                end
2772
                viteri, i = vy
12✔
2773
                vi        = v[viteri]
12✔
2774
            elseif isless(wj, vi)
40✔
2775
                wy = iterate(witer, j)
44✔
2776
                if wy === nothing
24✔
2777
                    break
4✔
2778
                end
2779
                witerj, j = wy
20✔
2780
                wj        = w[witerj]
20✔
2781
            else
2782
                push!(out, viteri)
16✔
2783
                vy = iterate(viter, i)
25✔
2784
                if vy === nothing
16✔
2785
                    break
1✔
2786
                end
2787
                # We only increment the v iterator because v can have
2788
                # repeated matches to a single value in w
2789
                viteri, i = vy
15✔
2790
                vi        = v[viteri]
15✔
2791
            end
2792
        end
47✔
2793
    end
2794
    return out
7✔
2795
end
2796

2797
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2798
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2799
        return _sortedfindin(x, pred.x)
9✔
2800
    else
2801
        return _findin(x, pred.x)
6✔
2802
    end
2803
end
2804
# issorted fails for some element types so the method above has to be restricted
2805
# to element with isless/< defined.
2806
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
373✔
2807
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2808

2809
# Copying subregions
2810
function indcopy(sz::Dims, I::Vector)
1✔
2811
    n = length(I)
1✔
2812
    s = sz[n]
1✔
2813
    for i = n+1:length(sz)
2✔
2814
        s *= sz[i]
×
2815
    end
×
2816
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2817
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2818
    dst, src
1✔
2819
end
2820

2821
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2822
    n = length(I)
1✔
2823
    s = sz[n]
1✔
2824
    for i = n+1:length(sz)
1✔
2825
        s *= sz[i]
×
2826
    end
×
2827
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2828
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2829
    dst, src
1✔
2830
end
2831

2832
## Filter ##
2833

2834
"""
2835
    filter(f, a)
2836

2837
Return a copy of collection `a`, removing elements for which `f` is `false`.
2838
The function `f` is passed one argument.
2839

2840
!!! compat "Julia 1.4"
2841
    Support for `a` as a tuple requires at least Julia 1.4.
2842

2843
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2844

2845
# Examples
2846
```jldoctest
2847
julia> a = 1:10
2848
1:10
2849

2850
julia> filter(isodd, a)
2851
5-element Vector{Int64}:
2852
 1
2853
 3
2854
 5
2855
 7
2856
 9
2857
```
2858
"""
2859
function filter(f, a::Array{T, N}) where {T, N}
18,416✔
2860
    j = 1
15,867✔
2861
    b = Vector{T}(undef, length(a))
36,709✔
2862
    for ai in a
18,416✔
2863
        @inbounds b[j] = ai
4,960,040✔
2864
        j = ifelse(f(ai)::Bool, j+1, j)
4,961,202✔
2865
    end
4,960,040✔
2866
    resize!(b, j-1)
18,416✔
2867
    sizehint!(b, length(b))
18,416✔
2868
    b
15,867✔
2869
end
2870

2871
function filter(f, a::AbstractArray)
452✔
2872
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
452✔
2873

2874
    j = 1
452✔
2875
    idxs = Vector{Int}(undef, length(a))
742✔
2876
    for idx in eachindex(a)
455✔
2877
        @inbounds idxs[j] = idx
103,369✔
2878
        ai = @inbounds a[idx]
103,369✔
2879
        j = ifelse(f(ai)::Bool, j+1, j)
104,902✔
2880
    end
206,447✔
2881
    resize!(idxs, j-1)
451✔
2882
    res = a[idxs]
451✔
2883
    empty!(idxs)
4,080✔
2884
    sizehint!(idxs, 0)
451✔
2885
    return res
451✔
2886
end
2887

2888
"""
2889
    filter!(f, a)
2890

2891
Update collection `a`, removing elements for which `f` is `false`.
2892
The function `f` is passed one argument.
2893

2894
# Examples
2895
```jldoctest
2896
julia> filter!(isodd, Vector(1:10))
2897
5-element Vector{Int64}:
2898
 1
2899
 3
2900
 5
2901
 7
2902
 9
2903
```
2904
"""
2905
function filter!(f, a::AbstractVector)
1,030,170✔
2906
    j = firstindex(a)
1,097✔
2907
    for ai in a
117,582,032✔
2908
        @inbounds a[j] = ai
137,790,904✔
2909
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
137,822,491✔
2910
    end
137,790,913✔
2911
    j > lastindex(a) && return a
117,582,031✔
2912
    if a isa Vector
374✔
2913
        resize!(a, j-1)
76,289✔
2914
        sizehint!(a, j-1)
76,289✔
2915
    else
2916
        deleteat!(a, j:lastindex(a))
1✔
2917
    end
2918
    return a
76,290✔
2919
end
2920

2921
"""
2922
    filter(f)
2923

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

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

2930
# Examples
2931
```jldoctest
2932
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2933
(1, 2, 4, 6)
2934

2935
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2936
3-element Vector{Vector{Int64}}:
2937
 [2]
2938
 [2, 4]
2939
 [4]
2940
```
2941
!!! compat "Julia 1.9"
2942
    This method requires at least Julia 1.9.
2943
"""
2944
function filter(f)
1✔
2945
    Fix1(filter, f)
1✔
2946
end
2947

2948
"""
2949
    keepat!(a::Vector, inds)
2950
    keepat!(a::BitVector, inds)
2951

2952
Remove the items at all the indices which are not given by `inds`,
2953
and return the modified `a`.
2954
Items which are kept are shifted to fill the resulting gaps.
2955

2956
$(_DOCS_ALIASING_WARNING)
2957

2958
`inds` must be an iterator of sorted and unique integer indices.
2959
See also [`deleteat!`](@ref).
2960

2961
!!! compat "Julia 1.7"
2962
    This function is available as of Julia 1.7.
2963

2964
# Examples
2965
```jldoctest
2966
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
2967
3-element Vector{Int64}:
2968
 6
2969
 4
2970
 2
2971
```
2972
"""
2973
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
2974

2975
"""
2976
    keepat!(a::Vector, m::AbstractVector{Bool})
2977
    keepat!(a::BitVector, m::AbstractVector{Bool})
2978

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

2983
# Examples
2984
```jldoctest
2985
julia> a = [:a, :b, :c];
2986

2987
julia> keepat!(a, [true, false, true])
2988
2-element Vector{Symbol}:
2989
 :a
2990
 :c
2991

2992
julia> a
2993
2-element Vector{Symbol}:
2994
 :a
2995
 :c
2996
```
2997
"""
2998
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
2999

3000
# set-like operators for vectors
3001
# These are moderately efficient, preserve order, and remove dupes.
3002

3003
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
384,370✔
3004
    # P, U force specialization
3005
    if pred(x, state)
756,235✔
3006
        update!(state, x)
18,949✔
3007
        true
3008
    else
3009
        false
3010
    end
3011
end
3012

3013
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
276✔
3014
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
4,175✔
3015

3016
function _grow!(pred!, v::AbstractVector, itrs)
106✔
3017
    filter!(pred!, v) # uniquify v
303✔
3018
    for itr in itrs
303✔
3019
        mapfilter(pred!, push!, itr, v)
593✔
3020
    end
876✔
3021
    return v
303✔
3022
end
3023

3024
union!(v::AbstractVector{T}, itrs...) where {T} =
271✔
3025
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3026

3027
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
3028
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3029

3030
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
2✔
3031
    seen = Set{eltype(v)}()
6✔
3032
    filter!(_grow_filter!(seen), v)
6✔
3033
    shrinker!(seen, itrs...)
6✔
3034
    filter!(in(seen), v)
6✔
3035
end
3036

3037
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
3038
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
3039

3040
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
4,143✔
3041

3042
function _shrink(shrinker!::F, itr, itrs) where F
4,047✔
3043
    T = promote_eltype(itr, itrs...)
3,945✔
3044
    keep = shrinker!(Set{T}(itr), itrs...)
5,105✔
3045
    vectorfilter(T, _shrink_filter!(keep), itr)
4,084✔
3046
end
3047

3048
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
511✔
3049
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
3,573✔
3050

3051
function intersect(v::AbstractVector, r::AbstractRange)
7✔
3052
    T = promote_eltype(v, r)
11✔
3053
    common = Iterators.filter(in(r), v)
59✔
3054
    seen = Set{T}(common)
59✔
3055
    return vectorfilter(T, _shrink_filter!(seen), common)
59✔
3056
end
3057
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
3058

3059
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3060
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
3,852✔
3061
    if i isa Bool # Not via dispatch to avoid ambiguities
30,247,678✔
3062
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3063
    else
3064
        _getindex(v, i)
528,994,154✔
3065
    end
3066
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