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

JuliaLang / julia / #38205

28 Aug 2025 06:55AM UTC coverage: 77.955% (-0.003%) from 77.958%
#38205

push

local

web-flow
PCRE2: New version 10.46 (#59416)

48572 of 62308 relevant lines covered (77.95%)

10154018.81 hits per line

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

92.22
/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
4,022✔
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}()
217,664✔
159
function vect(X::T...) where T
10,189✔
160
    @_terminates_locally_meta
118,070✔
161
    vec = Vector{T}(undef, length(X))
130,434✔
162
    @_safeindex for i = 1:length(X)
139,897✔
163
        vec[i] = X[i]
283,309✔
164
    end
431,583✔
165
    return vec
126,109✔
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...)
403,545✔
184
    T = promote_typeof(X...)
403,863✔
185
    return T[X...]
404,042✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
16,455✔
190
    d < 1 && error("arraysize: dimension out of range")
65,261,590✔
191
    sz = getfield(a, :size)
65,387,778✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
97,580,620✔
193
end
194
size(a::Array) = getfield(a, :size)
830,145,421✔
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))
20,764✔
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)
×
215

216
function _unsetindex!(A::Array, i::Int)
1,317✔
217
    @inline
148,594,070✔
218
    @boundscheck checkbounds(A, i)
155,475,321✔
219
    @inbounds _unsetindex!(memoryref(A.ref, i))
156,049,477✔
220
    return A
149,298,729✔
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)
113,872,498✔
226
function elsize(::Type{Ptr{T}}) where T
7✔
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})
7✔
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
79,032✔
236

237
function isassigned(a::Array, i::Int...)
46,319✔
238
    @inline
381,918✔
239
    @_noub_if_noinbounds_meta
381,918✔
240
    @boundscheck checkbounds(Bool, a, i...) || return false
381,928✔
241
    ii = _sub2ind(size(a), i...)
381,908✔
242
    return @inbounds isassigned(memoryrefnew(a.ref, ii, false))
381,908✔
243
end
244

245
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
92✔
246
    @inline
28,567,596✔
247
    @_noub_if_noinbounds_meta
28,568,019✔
248
    @boundscheck checkbounds(Bool, a, i) || return false
28,695,162✔
249
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
28,727,360✔
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
4,091✔
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))
8,755,170✔
269
    return dest
7,866,697✔
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)
6✔
283
    n == 0 && return dest
3,264,380✔
284
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
6,466,863✔
285
    return dest
3,233,436✔
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)
65,910✔
295
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
129✔
296
copyto!(dest::Memory, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
51,165,295✔
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)
5,305,215✔
300

301
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
62✔
302
    n == 0 && return dest
28,442,564✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
28,179,319✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
28,180,234✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
28,180,177✔
306
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
28,180,191✔
307
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
55,349,637✔
309
    end
310
    return dest
27,169,535✔
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)))
4✔
318

319
_copyto2arg!(dest, src) = copyto!(dest, firstindex(dest), src, firstindex(src), length(src))
890,774✔
320

321
copyto!(dest::Array, src::Array) = _copyto2arg!(dest, src)
37,692✔
322
copyto!(dest::Array, src::Memory) = _copyto2arg!(dest, src)
×
323
copyto!(dest::Memory, src::Array) = _copyto2arg!(dest, src)
×
324

325
# also to avoid ambiguities in packages
326
copyto!(dest::Array{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
852,940✔
327
copyto!(dest::Array{T}, src::Memory{T}) where {T} = _copyto2arg!(dest, src)
129✔
328
copyto!(dest::Memory{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
13✔
329

330
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
331
# for bootstrapping purposes.
332
function fill!(dest::Array{T}, x) where T
6,647✔
333
    @inline
7,436,394✔
334
    x = x isa T ? x : convert(T, x)::T
7,436,435✔
335
    return _fill!(dest, x)
1,753,111,176✔
336
end
337
function _fill!(dest::Array{T}, x::T) where T
5,673✔
338
    for i in eachindex(dest)
11,443,465✔
339
        dest[i] = x
1,768,976,676✔
340
    end
2,147,483,647✔
341
    return dest
7,560,623✔
342
end
343

344
"""
345
    copy(x)
346

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

351
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
352
"""
353
copy
354

355
@eval function copy(a::Array)
156,299✔
356
    # `copy` only throws when the size exceeds the max allocation size,
357
    # but since we're copying an existing array, we're guaranteed that this will not happen.
358
    @_nothrow_meta
2,225,516✔
359
    ref = a.ref
2,821,390✔
360
    newmem = typeof(ref.mem)(undef, length(a))
2,821,382✔
361
    @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a))
4,983,908✔
362
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
2,821,289✔
363
end
364

365
# a mutating version of copyto! that results in dst aliasing src afterwards
366
function _take!(dst::Array{T,N}, src::Array{T,N}) where {T,N}
367
    if getfield(dst, :ref) !== getfield(src, :ref)
165✔
368
        setfield!(dst, :ref, getfield(src, :ref))
15✔
369
    end
370
    if getfield(dst, :size) !== getfield(src, :size)
165✔
371
        setfield!(dst, :size, getfield(src, :size))
162✔
372
    end
373
    return dst
165✔
374
end
375

376
## Constructors ##
377

378
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
120,782✔
379
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
4,292✔
380
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
10,088✔
381
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
11,958✔
382
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
20,880✔
383
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
3,889,639✔
384
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
474✔
385
similar(::Type{Array{T,N}}, dims::Dims) where {T,N} = similar(Array{T}, dims)
15,727,568✔
386

387
# T[x...] constructs Array{T,1}
388
"""
389
    getindex(type[, elements...])
390

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

394
# Examples
395
```jldoctest
396
julia> Int8[1, 2, 3]
397
3-element Vector{Int8}:
398
 1
399
 2
400
 3
401

402
julia> getindex(Int8, 1, 2, 3)
403
3-element Vector{Int8}:
404
 1
405
 2
406
 3
407
```
408
"""
409
function getindex(::Type{T}, vals...) where T
88,147✔
410
    @inline
7,108,488✔
411
    @_effect_free_terminates_locally_meta
7,108,487✔
412
    a = Vector{T}(undef, length(vals))
32,969,108✔
413
    if vals isa NTuple
7,108,488✔
414
        @_safeindex for i in 1:length(vals)
7,048,991✔
415
            a[i] = vals[i]
618,440✔
416
        end
602,355✔
417
    else
418
        # use afoldl to avoid type instability inside loop
419
        afoldl(1, vals...) do i, v
59,646✔
420
            @inbounds a[i] = v
125,957✔
421
            return i + 1
125,957✔
422
        end
423
    end
424
    return a
7,108,473✔
425
end
426

427
function getindex(::Type{Any}, @nospecialize vals...)
691,462✔
428
    @_effect_free_terminates_locally_meta
758,587✔
429
    a = Vector{Any}(undef, length(vals))
773,091✔
430
    @_safeindex for i = 1:length(vals)
1,198,361✔
431
        a[i] = vals[i]
2,048,091✔
432
    end
3,292,015✔
433
    return a
759,656✔
434
end
435
getindex(::Type{Any}) = Vector{Any}()
25,689,330✔
436

437
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
12✔
438
    ref = a.ref
154,893✔
439
    t = @_gc_preserve_begin ref
154,893✔
440
    p = unsafe_convert(Ptr{Cvoid}, ref)
154,893✔
441
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
154,896✔
442
    @_gc_preserve_end t
154,890✔
443
    return a
80,085✔
444
end
445

446
to_dim(d::Integer) = d
×
447
to_dim(d::OneTo) = last(d)
212✔
448

449
"""
450
    fill(value, dims::Tuple)
451
    fill(value, dims...)
452

453
Create an array of size `dims` with every location set to `value`.
454

455
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
456
with `1.0` in every location of the array.
457

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

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

471
```jldoctest
472
julia> v = fill([], 3)
473
3-element Vector{Vector{Any}}:
474
 []
475
 []
476
 []
477

478
julia> v[1] === v[2] === v[3]
479
true
480

481
julia> value = v[1]
482
Any[]
483

484
julia> push!(value, 867_5309)
485
1-element Vector{Any}:
486
 8675309
487

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

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

498
```jldoctest
499
julia> v2 = [[] for _ in 1:3]
500
3-element Vector{Vector{Any}}:
501
 []
502
 []
503
 []
504

505
julia> v2[1] === v2[2] === v2[3]
506
false
507

508
julia> push!(v2[1], 8675309)
509
1-element Vector{Any}:
510
 8675309
511

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

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

521
# Examples
522
```jldoctest
523
julia> fill(1.0, (2,3))
524
2×3 Matrix{Float64}:
525
 1.0  1.0  1.0
526
 1.0  1.0  1.0
527

528
julia> fill(42)
529
0-dimensional Array{Int64, 0}:
530
42
531

532
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
533
2-element Vector{Vector{Float64}}:
534
 [0.0, 0.0]
535
 [0.0, 0.0]
536

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

539
julia> A # both A[1] and A[2] are the very same vector
540
2-element Vector{Vector{Float64}}:
541
 [42.0, 0.0]
542
 [42.0, 0.0]
543
```
544
"""
545
function fill end
546

547
fill(v, dims::DimOrInd...) = fill(v, dims)
37,108,602✔
548
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
549
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
37,108,646✔
550
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
14✔
551
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
180✔
552

553
"""
554
    zeros([T=Float64,] dims::Tuple)
555
    zeros([T=Float64,] dims...)
556

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

560
# Examples
561
```jldoctest
562
julia> zeros(1)
563
1-element Vector{Float64}:
564
 0.0
565

566
julia> zeros(Int8, 2, 3)
567
2×3 Matrix{Int8}:
568
 0  0  0
569
 0  0  0
570
```
571
"""
572
function zeros end
573

574
"""
575
    ones([T=Float64,] dims::Tuple)
576
    ones([T=Float64,] dims...)
577

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

581
# Examples
582
```jldoctest
583
julia> ones(1,2)
584
1×2 Matrix{Float64}:
585
 1.0  1.0
586

587
julia> ones(ComplexF64, 2, 3)
588
2×3 Matrix{ComplexF64}:
589
 1.0+0.0im  1.0+0.0im  1.0+0.0im
590
 1.0+0.0im  1.0+0.0im  1.0+0.0im
591
```
592
"""
593
function ones end
594

595
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
596
    @eval begin
597
        $fname(dims::DimOrInd...) = $fname(dims)
216,508✔
598
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
1,276,674,853✔
599
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
222,289✔
600
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,264✔
601
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
12,103✔
602
            a = Array{T,N}(undef, dims)
1,652,030✔
603
            fill!(a, $felt(T))
1,702,349,070✔
604
            return a
1,577,108✔
605
        end
606
        function $fname(::Type{T}, dims::Tuple{}) where {T}
607
            a = Array{T}(undef)
20✔
608
            fill!(a, $felt(T))
20✔
609
            return a
20✔
610
        end
611
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
612
            a = similar(Array{T,N}, dims)
1,654✔
613
            fill!(a, $felt(T))
3,708✔
614
            return a
1,654✔
615
        end
616
    end
617
end
618

619
## Conversions ##
620

621
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
59,543✔
622

623
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
98✔
624

625
## Constructors ##
626

627
# constructors should make copies
628
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
53,733✔
629
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
8,149✔
630

631
## copying iterators to containers
632

633
"""
634
    collect(element_type, collection)
635

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

639
# Examples
640
```jldoctest
641
julia> collect(Float64, 1:2:5)
642
3-element Vector{Float64}:
643
 1.0
644
 3.0
645
 5.0
646
```
647
"""
648
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
135,846✔
649

650
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
6,407✔
651
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
652
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
129,416✔
653
    a = Vector{T}()
129,423✔
654
    for x in itr
248,390✔
655
        push!(a, x)
199,724✔
656
    end
280,480✔
657
    return a
129,423✔
658
end
659

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

663
_similar_shape(itr, ::SizeUnknown) = nothing
139✔
664
_similar_shape(itr, ::HasLength) = length(itr)::Integer
777,988✔
665
_similar_shape(itr, ::HasShape) = axes(itr)
15,528,027✔
666

667
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
467,588✔
668
    similar(c, T, 0)
669
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
95,361✔
670
    similar(c, T, len)
671
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
193,592✔
672
    similar(c, T, axs)
673

674
# make a collection appropriate for collecting `itr::Generator`
675
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
139✔
676
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
659,452✔
677
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
12,639,867✔
678

679
# used by syntax lowering for simple typed comprehensions
680
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
15,160,634✔
681

682

683
"""
684
    collect(iterator)
685

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

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

695
The element type of the returned array is based on the types of the values collected. However, if the
696
iterator is empty then the element type of the returned (empty) array is determined by type inference.
697

698
# Examples
699

700
Collect items from a `UnitRange{Int64}` collection:
701

702
```jldoctest
703
julia> collect(1:3)
704
3-element Vector{Int64}:
705
 1
706
 2
707
 3
708
```
709

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

712
```jldoctest
713
julia> collect(x^2 for x in 1:3)
714
3-element Vector{Int64}:
715
 1
716
 4
717
 9
718
```
719

720
Collecting an empty iterator where the result type depends on type inference:
721

722
```jldoctest
723
julia> [rand(Bool) ? 1 : missing for _ in []]
724
Union{Missing, Int64}[]
725
```
726

727
When the iterator is non-empty, the result type depends only on values:
728

729
```julia-repl
730
julia> [rand(Bool) ? 1 : missing for _ in [""]]
731
1-element Vector{Int64}:
732
 1
733
```
734
"""
735
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
1,055,583✔
736

737
collect(A::AbstractArray) = _collect_indices(axes(A), A)
138,531✔
738

739
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
261,082✔
740

741
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
79,160✔
742
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
743

744
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
467,507✔
745
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
467,561✔
746
    for x in itr
933,751✔
747
        push!(a,x)
8,117,374✔
748
    end
14,157,508✔
749
    return a
467,228✔
750
end
751

752
function _collect_indices(::Tuple{}, A)
753
    dest = Array{eltype(A),0}(undef)
26✔
754
    isempty(A) && return dest
26✔
755
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
26✔
756
end
757
function _collect_indices(indsA::Tuple{Vararg{OneTo}}, A)
4,757✔
758
    dest = Array{eltype(A)}(undef, length.(indsA))
93,900✔
759
    isempty(A) && return dest
93,900✔
760
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
93,887✔
761
end
762
function _collect_indices(indsA, A)
36✔
763
    B = Array{eltype(A)}(undef, length.(indsA))
121✔
764
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
765
end
766

767
# NOTE: this function is not meant to be called, only inferred, for the
768
# purpose of bounding the types of values generated by an iterator.
769
function _iterator_upper_bound(itr)
×
770
    x = iterate(itr)
×
771
    while x !== nothing
×
772
        val = getfield(x, 1)
×
773
        if inferencebarrier(nothing)
×
774
            return val
×
775
        end
776
        x = iterate(itr, getfield(x, 2))
×
777
    end
×
778
    throw(nothing)
×
779
end
780

781
# define this as a macro so that the call to Core.Compiler
782
# gets inlined into the caller before recursion detection
783
# gets a chance to see it, so that recursive calls to the caller
784
# don't trigger the inference limiter
785
macro default_eltype(itr)
786
    I = esc(itr)
787
    return quote
788
        if $I isa Generator && ($I).f isa Type
1,263,598✔
789
            T = ($I).f
12,817✔
790
        else
791
            T = Base._return_type(_iterator_upper_bound, Tuple{typeof($I)})
1,250,784✔
792
        end
793
        promote_typejoin_union(T)
1,263,607✔
794
    end
795
end
796

797
function collect(itr::Generator)
514,800✔
798
    isz = IteratorSize(itr.iter)
974,994✔
799
    et = @default_eltype(itr)
800
    if isa(isz, SizeUnknown)
974,993✔
801
        return grow_to!(Vector{et}(), itr)
111,190✔
802
    else
803
        shp = _similar_shape(itr, isz)
864,633✔
804
        y = iterate(itr)
1,368,632✔
805
        if y === nothing
863,834✔
806
            return _array_for(et, isz, shp)
766✔
807
        end
808
        v1, st = y
863,068✔
809
        dest = _array_for(typeof(v1), isz, shp)
863,230✔
810
        # The typeassert gives inference a helping hand on the element type and dimensionality
811
        # (work-around for #28382)
812
        et′ = et <: Type ? Type : et
863,068✔
813
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
863,224✔
814
        collect_to_with_first!(dest, v1, itr, st)::RT
10,853,072✔
815
    end
816
end
817

818
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
57✔
819
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
820

821
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
105,709✔
822
    et = @default_eltype(itr)
131,954✔
823
    shp = _similar_shape(itr, isz)
192,335✔
824
    y = iterate(itr)
383,334✔
825
    if y === nothing
192,317✔
826
        return _similar_for(c, et, itr, isz, shp)
1,226✔
827
    end
828
    v1, st = y
130,727✔
829
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
191,158✔
830
    # The typeassert gives inference a helping hand on the element type and dimensionality
831
    # (work-around for #28382)
832
    et′ = et <: Type ? Type : et
130,727✔
833
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
130,782✔
834
    collect_to_with_first!(dest, v1, itr, st)::RT
191,091✔
835
end
836

837
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
103,120✔
838
    i1 = first(LinearIndices(dest))
994,231✔
839
    dest[i1] = v1
1,054,104✔
840
    return collect_to!(dest, itr, i1+1, st)
11,341,088✔
841
end
842

843
function collect_to_with_first!(dest, v1, itr, st)
×
844
    push!(dest, v1)
×
845
    return grow_to!(dest, itr, st)
×
846
end
847

848
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
1,716✔
849
    @inline
1,897✔
850
    new = similar(dest, promote_typejoin(T, typeof(el)))
1,900✔
851
    f = first(LinearIndices(dest))
1,897✔
852
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
3,784✔
853
    @inbounds new[i] = el
1,900✔
854
    return new
1,900✔
855
end
856

857
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
499,101✔
858
    # collect to dest array, checking the type of each result. if a result does not
859
    # match, widen the result type and re-dispatch.
860
    i = offs
996,062✔
861
    while true
119,219,242✔
862
        y = iterate(itr, st)
213,549,502✔
863
        y === nothing && break
119,219,236✔
864
        el, st = y
117,868,208✔
865
        if el isa T
117,868,208✔
866
            @inbounds dest[i] = el
118,163,302✔
867
            i += 1
118,163,302✔
868
        else
869
            new = setindex_widen_up_to(dest, el, i)
1,888✔
870
            return collect_to!(new, itr, i+1, st)
1,888✔
871
        end
872
    end
118,163,302✔
873
    return dest
1,054,046✔
874
end
875

876
function grow_to!(dest, itr)
1,548✔
877
    y = iterate(itr)
111,834✔
878
    y === nothing && return dest
111,223✔
879
    dest2 = empty(dest, typeof(y[1]))
643✔
880
    push!(dest2, y[1])
736✔
881
    grow_to!(dest2, itr, y[2])
636✔
882
end
883

884
function push_widen(dest, el)
52✔
885
    @inline
54✔
886
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
54✔
887
    if new isa AbstractSet
54✔
888
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
889
        union!(new, dest)
×
890
    else
891
        append!(new, dest)
108✔
892
    end
893
    push!(new, el)
54✔
894
    return new
54✔
895
end
896

897
function grow_to!(dest, itr, st)
682✔
898
    T = eltype(dest)
696✔
899
    y = iterate(itr, st)
1,183✔
900
    while y !== nothing
4,175✔
901
        el, st = y
3,533✔
902
        if el isa T
3,533✔
903
            push!(dest, el)
3,481✔
904
        else
905
            new = push_widen(dest, el)
56✔
906
            return grow_to!(new, itr, st)
54✔
907
        end
908
        y = iterate(itr, st)
4,607✔
909
    end
3,479✔
910
    return dest
642✔
911
end
912

913
## Indexing: getindex ##
914

915
"""
916
    getindex(collection, key...)
917

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

921
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
922

923
# Examples
924
```jldoctest; filter = r"^\\s+\\S+\\s+=>\\s+\\d\$"m
925
julia> A = Dict("a" => 1, "b" => 2)
926
Dict{String, Int64} with 2 entries:
927
  "b" => 2
928
  "a" => 1
929

930
julia> getindex(A, "a")
931
1
932
```
933
"""
934
function getindex end
935

936
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
56,326✔
937
    @inline
144,148,060✔
938
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
189,904,819✔
939
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
189,906,597✔
940
end
941

942
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
943
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
25,259✔
944
    @inline
1,448,631✔
945
    @boundscheck checkbounds(A, I)
3,522,378✔
946
    lI = length(I)
3,522,372✔
947
    X = similar(A, axes(I))
3,522,382✔
948
    if lI > 0
3,522,376✔
949
        copyto!(X, firstindex(X), A, first(I), lI)
3,959,199✔
950
    end
951
    return X
3,517,561✔
952
end
953

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

957
function getindex(A::Array, c::Colon)
4,455✔
958
    lI = length(A)
18,115✔
959
    X = similar(A, lI)
18,115✔
960
    if lI > 0
18,115✔
961
        unsafe_copyto!(X, 1, A, 1, lI)
36,226✔
962
    end
963
    return X
18,115✔
964
end
965

966
# This is redundant with the abstract fallbacks, but needed for bootstrap
967
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
3,169,691✔
968
    return S[ A[i] for i in I ]
3,169,931✔
969
end
970

971
## Indexing: setindex! ##
972

973
"""
974
    setindex!(collection, value, key...)
975

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

979
# Examples
980
```jldoctest; filter = r"^\\s+\\S+\\s+=>\\s+\\d\$"m
981
julia> a = Dict("a"=>1)
982
Dict{String, Int64} with 1 entry:
983
  "a" => 1
984

985
julia> setindex!(a, 2, "b")
986
Dict{String, Int64} with 2 entries:
987
  "b" => 2
988
  "a" => 1
989
```
990
"""
991
function setindex! end
992

993
function setindex!(A::Array{T}, x, i::Int) where {T}
3,333,384✔
994
    @_propagate_inbounds_meta
2,147,483,647✔
995
    x = x isa T ? x : convert(T, x)::T
2,147,483,647✔
996
    return _setindex!(A, x, i)
2,147,483,647✔
997
end
998
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
7,165✔
999
    @_noub_if_noinbounds_meta
2,147,483,647✔
1000
    @boundscheck checkbounds(Bool, A, i) || throw_boundserror(A, (i,))
2,147,483,647✔
1001
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
2,147,483,647✔
1002
    return A
2,147,483,647✔
1003
end
1004
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,648✔
1005
    @_propagate_inbounds_meta
61,445,282✔
1006
    x = x isa T ? x : convert(T, x)::T
61,449,150✔
1007
    return _setindex!(A, x, i1, i2, I...)
78,401,608✔
1008
end
1009
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
4✔
1010
    @inline
60,396,778✔
1011
    @_noub_if_noinbounds_meta
60,396,778✔
1012
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
78,406,340✔
1013
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
78,407,427✔
1014
    return A
77,438,691✔
1015
end
1016

1017
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
150,651,417✔
1018
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
152,859,828✔
1019
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
28,707,034✔
1020
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
79,897,441✔
1021
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
1022
    __safe_setindex!(A, convert(T, x)::T, i))
36,445✔
1023

1024
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1025
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
99✔
1026
    @_propagate_inbounds_meta
824,831✔
1027
    @boundscheck setindex_shape_check(X, length(I))
842,770✔
1028
    @boundscheck checkbounds(A, I)
842,770✔
1029
    require_one_based_indexing(X)
824,831✔
1030
    X′ = unalias(A, X)
825,320✔
1031
    I′ = unalias(A, I)
824,832✔
1032
    count = 1
824,831✔
1033
    for i in I′
870,957✔
1034
        @inbounds A[i] = X′[count]
5,940,792✔
1035
        count += 1
5,940,792✔
1036
    end
11,085,721✔
1037
    return A
838,795✔
1038
end
1039

1040
# Faster contiguous setindex! with copyto!
1041
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
113✔
1042
    @inline
1,013,140✔
1043
    @boundscheck checkbounds(A, I)
1,013,246✔
1044
    lI = length(I)
1,013,246✔
1045
    @boundscheck setindex_shape_check(X, lI)
1,013,246✔
1046
    if lI > 0
1,013,246✔
1047
        unsafe_copyto!(A, first(I), X, 1, lI)
2,025,870✔
1048
    end
1049
    return A
1,013,216✔
1050
end
1051
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
44✔
1052
    @inline
74✔
1053
    lI = length(A)
74✔
1054
    @boundscheck setindex_shape_check(X, lI)
74✔
1055
    if lI > 0
74✔
1056
        unsafe_copyto!(A, 1, X, 1, lI)
148✔
1057
    end
1058
    return A
74✔
1059
end
1060

1061
# Pick new memory size for efficiently growing an array
1062
# TODO: This should know about the size of our GC pools
1063
# Specifically we are wasting ~10% of memory for small arrays
1064
# by not picking memory sizes that max out a GC pool
1065
function overallocation(maxsize)
442✔
1066
    maxsize < 8 && return 8;
11,780,079✔
1067
    # compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
1068
    # for small n, we grow faster than O(n)
1069
    # for large n, we grow at O(n/8)
1070
    # and as we reach O(memory) for memory>>1MB,
1071
    # this means we end by adding about 10% of memory each time
1072
    exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
1,176,108✔
1073
    maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8)
1,176,005✔
1074
    return maxsize
1,175,547✔
1075
end
1076

1077
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
11,758,268✔
1078

1079
function _growbeg_internal!(a::Vector, delta::Int, len::Int)
207,168✔
1080
    @_terminates_locally_meta
207,169✔
1081
    ref = a.ref
207,168✔
1082
    mem = ref.mem
207,126✔
1083
    offset = memoryrefoffset(ref)
207,162✔
1084
    newlen = len + delta
207,165✔
1085
    memlen = length(mem)
207,143✔
1086
    if offset + len - 1 > memlen || offset < 1
414,217✔
1087
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1088
    end
1089
    # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1090
    # the +1 is because I didn't want to have an off by 1 error.
1091
    newmemlen = max(overallocation(len), len + 2 * delta + 1)
306,961✔
1092
    newoffset = div(newmemlen - newlen, 2) + 1
207,046✔
1093
    # If there is extra data after the end of the array we can use that space so long as there is enough
1094
    # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1095
    # Specifically, we want to ensure that we will only do this operation once before
1096
    # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1097
    if newoffset + newlen < memlen
207,063✔
1098
        newoffset = div(memlen - newlen, 2) + 1
2,100✔
1099
        newmem = mem
2,100✔
1100
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
2,698✔
1101
        for j in offset:newoffset+delta-1
2,332✔
1102
            @inbounds _unsetindex!(mem, j)
35,016✔
1103
        end
53,028✔
1104
    else
1105
        newmem = array_new_memory(mem, newmemlen)
205,008✔
1106
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
205,008✔
1107
    end
1108
    if ref !== a.ref
207,118✔
1109
        throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1110
    end
1111
    setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
207,107✔
1112
end
1113

1114
function _growbeg!(a::Vector, delta::Integer)
27✔
1115
    @_noub_meta
6,340,283✔
1116
    delta = Int(delta)
6,340,285✔
1117
    delta == 0 && return # avoid attempting to index off the end
6,349,719✔
1118
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
6,349,402✔
1119
    ref = a.ref
6,631,156✔
1120
    mem = ref.mem
6,340,199✔
1121
    len = length(a)
6,631,155✔
1122
    offset = memoryrefoffset(ref)
6,631,161✔
1123
    newlen = len + delta
6,631,159✔
1124
    setfield!(a, :size, (newlen,))
6,631,147✔
1125
    # if offset is far enough advanced to fit data in existing memory without copying
1126
    if delta <= offset - 1
6,631,146✔
1127
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
6,414,934✔
1128
    else
1129
        @noinline _growbeg_internal!(a, delta, len)
216,226✔
1130
    end
1131
    return
6,631,145✔
1132
end
1133

1134
function _growend_internal!(a::Vector, delta::Int, len::Int)
10,827,018✔
1135
    ref = a.ref
10,827,039✔
1136
    mem = ref.mem
10,826,897✔
1137
    memlen = length(mem)
10,827,613✔
1138
    newlen = len + delta
10,827,559✔
1139
    offset = memoryrefoffset(ref)
10,827,434✔
1140
    newmemlen = offset + newlen - 1
10,827,442✔
1141
    if offset + len - 1 > memlen || offset < 1
21,654,719✔
1142
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1143
    end
1144

1145
    if offset - 1 > div(5 * newlen, 4)
10,827,200✔
1146
        # If the offset is far enough that we can copy without resizing
1147
        # while maintaining proportional spacing on both ends of the array
1148
        # note that this branch prevents infinite growth when doing combinations
1149
        # of push! and popfirst! (i.e. when using a Vector as a queue)
1150
        newmem = mem
282✔
1151
        newoffset = div(newlen, 8) + 1
282✔
1152
    else
1153
        # grow either by our computed overallocation factor
1154
        # or exactly the requested size, whichever is larger
1155
        # TODO we should possibly increase the offset if the current offset is nonzero.
1156
        newmemlen2 = max(overallocation(memlen), newmemlen)
11,375,776✔
1157
        newmem = array_new_memory(mem, newmemlen2)
10,828,222✔
1158
        newoffset = offset
10,826,942✔
1159
    end
1160
    newref = @inbounds memoryref(newmem, newoffset)
10,827,246✔
1161
    unsafe_copyto!(newref, ref, len)
11,560,714✔
1162
    if ref !== a.ref
10,827,036✔
1163
        @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1164
    end
1165
    setfield!(a, :ref, newref)
10,826,921✔
1166
return
10,826,915✔
1167
end
1168

1169
function _growend!(a::Vector, delta::Integer)
735✔
1170
    @_noub_meta
185,832,962✔
1171
    delta = Int(delta)
185,834,458✔
1172
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
185,984,489✔
1173
    ref = a.ref
229,700,084✔
1174
    mem = ref.mem
229,698,374✔
1175
    memlen = length(mem)
229,723,133✔
1176
    len = length(a)
229,718,661✔
1177
    newlen = len + delta
229,717,917✔
1178
    offset = memoryrefoffset(ref)
229,714,242✔
1179
    setfield!(a, :size, (newlen,))
229,714,240✔
1180
    newmemlen = offset + newlen - 1
229,714,237✔
1181
    if memlen < newmemlen
229,721,299✔
1182
        @noinline _growend_internal!(a, delta, len)
12,682,126✔
1183
    end
1184
    return
229,666,244✔
1185
end
1186

1187
function _growat!(a::Vector, i::Integer, delta::Integer)
663,254✔
1188
    @_terminates_globally_noub_meta
663,258✔
1189
    delta = Int(delta)
663,258✔
1190
    i = Int(i)
663,227✔
1191
    i == 1 && return _growbeg!(a, delta)
663,252✔
1192
    len = length(a)
455,481✔
1193
    i == len + 1 && return _growend!(a, delta)
455,477✔
1194
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
378,374✔
1195
    1 < i <= len || throw(BoundsError(a, i))
378,376✔
1196
    ref = a.ref
378,372✔
1197
    mem = ref.mem
378,372✔
1198
    memlen = length(mem)
378,372✔
1199
    newlen = len + delta
378,372✔
1200
    offset = memoryrefoffset(ref)
378,372✔
1201
    setfield!(a, :size, (newlen,))
378,372✔
1202
    newmemlen = offset + newlen - 1
378,372✔
1203

1204
    # which side would we rather grow into?
1205
    prefer_start = i <= div(len, 2)
378,372✔
1206
    # if offset is far enough advanced to fit data in beginning of the memory
1207
    if prefer_start && delta <= offset - 1
378,372✔
1208
        newref = @inbounds memoryref(mem, offset - delta)
128,319✔
1209
        unsafe_copyto!(newref, ref, i)
256,638✔
1210
        setfield!(a, :ref, newref)
128,319✔
1211
        for j in i:i+delta-1
187,295✔
1212
            @inbounds _unsetindex!(a, j)
158,769✔
1213
        end
152,051✔
1214
    elseif !prefer_start && memlen >= newmemlen
250,053✔
1215
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
368,758✔
1216
        for j in i:i+delta-1
244,642✔
1217
            @inbounds _unsetindex!(a, j)
217,475✔
1218
        end
208,286✔
1219
    else
1220
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1221
        # the +1 is because I didn't want to have an off by 1 error.
1222
        newmemlen = max(overallocation(memlen), len+2*delta+1)
110,828✔
1223
        newoffset = (newmemlen - newlen) ÷ 2 + 1
65,674✔
1224
        newmem = array_new_memory(mem, newmemlen)
65,674✔
1225
        newref = @inbounds memoryref(newmem, newoffset)
65,674✔
1226
        unsafe_copyto!(newref, ref, i-1)
131,348✔
1227
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
131,348✔
1228
        setfield!(a, :ref, newref)
65,674✔
1229
    end
1230
end
1231

1232
# efficiently delete part of an array
1233
function _deletebeg!(a::Vector, delta::Integer)
76,103✔
1234
    delta = Int(delta)
7,817,545✔
1235
    len = length(a)
9,124,254✔
1236
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
9,124,254✔
1237
    for i in 1:delta
7,890,214✔
1238
        @inbounds _unsetindex!(a, i)
18,671,892✔
1239
    end
26,673,502✔
1240
    newlen = len - delta
9,124,250✔
1241
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
9,124,250✔
1242
        newref = @inbounds memoryref(a.ref, delta + 1)
9,008,314✔
1243
        setfield!(a, :ref, newref)
9,008,313✔
1244
    end
1245
    setfield!(a, :size, (newlen,))
9,124,251✔
1246
    return
9,124,251✔
1247
end
1248
function _deleteend!(a::Vector, delta::Integer)
128✔
1249
    delta = Int(delta)
5,289,413✔
1250
    len = length(a)
10,388,369✔
1251
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
10,388,376✔
1252
    newlen = len - delta
10,388,398✔
1253
    for i in newlen+1:len
15,317,181✔
1254
        @inbounds _unsetindex!(a, i)
130,296,177✔
1255
    end
249,667,616✔
1256
    setfield!(a, :size, (newlen,))
10,388,346✔
1257
    return
10,388,341✔
1258
end
1259
function _deleteat!(a::Vector, i::Integer, delta::Integer)
163,904✔
1260
    i = Int(i)
163,904✔
1261
    len = length(a)
163,903✔
1262
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
163,904✔
1263
    1 <= i <= len || throw(BoundsError(a, i))
163,904✔
1264
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
163,916✔
1265
    newa = a
163,914✔
1266
    if 2*i + delta <= len
163,914✔
1267
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
88,885✔
1268
        _deletebeg!(a, delta)
9,463,000✔
1269
    else
1270
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
208,144✔
1271
        _deleteend!(a, delta)
117,857✔
1272
    end
1273
    return
163,891✔
1274
end
1275
## Dequeue functionality ##
1276

1277
"""
1278
    push!(collection, items...) -> collection
1279

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

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

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

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

1301
See also [`pushfirst!`](@ref).
1302
"""
1303
function push! end
1304

1305
function push!(a::Vector{T}, item) where T
29,562✔
1306
    @inline
29,775,646✔
1307
    # convert first so we don't grow the array if the assignment won't work
1308
    # and also to avoid a dynamic dynamic dispatch in the common case that
1309
    # `item` is poorly-typed and `a` is well-typed
1310
    item = item isa T ? item : convert(T, item)::T
29,800,455✔
1311
    return _push!(a, item)
72,968,139✔
1312
end
1313
function _push!(a::Vector{T}, item::T) where T
665✔
1314
    _growend!(a, 1)
72,966,134✔
1315
    @_safeindex a[length(a)] = item
72,977,555✔
1316
    return a
72,955,636✔
1317
end
1318

1319
# specialize and optimize the single argument case
1320
function push!(a::Vector{Any}, @nospecialize x)
638✔
1321
    _growend!(a, 1)
150,419,812✔
1322
    @_safeindex a[length(a)] = x
150,419,787✔
1323
    return a
150,419,773✔
1324
end
1325
function push!(a::Vector{Any}, @nospecialize x...)
17✔
1326
    @_terminates_locally_meta
37✔
1327
    na = length(a)
37✔
1328
    nx = length(x)
37✔
1329
    _growend!(a, nx)
37✔
1330
    @_safeindex for i = 1:nx
37✔
1331
        a[na+i] = x[i]
131✔
1332
    end
225✔
1333
    return a
37✔
1334
end
1335

1336
"""
1337
    append!(collection, collections...) -> collection.
1338

1339
For an ordered container `collection`, add the elements of each `collections`
1340
to the end of it.
1341

1342
!!! compat "Julia 1.6"
1343
    Specifying multiple collections to be appended requires at least Julia 1.6.
1344

1345
# Examples
1346
```jldoctest
1347
julia> append!([1], [2, 3])
1348
3-element Vector{Int64}:
1349
 1
1350
 2
1351
 3
1352

1353
julia> append!([1, 2, 3], [4, 5], [6])
1354
6-element Vector{Int64}:
1355
 1
1356
 2
1357
 3
1358
 4
1359
 5
1360
 6
1361
```
1362

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

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

1369
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1370
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1371
"""
1372
function append! end
1373

1374
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
10,228✔
1375
    items isa Tuple && (items = map(x -> convert(T, x), items))
2,511,915✔
1376
    n = Int(length(items))::Int
1,070,768✔
1377
    _growend!(a, n)
1,073,866✔
1378
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
1,143,996✔
1379
    return a
1,073,863✔
1380
end
1381

1382
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
184,288✔
1383
push!(a::AbstractVector, iter...) = append!(a, iter)
742,721✔
1384
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
19✔
1385

1386
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
116,708✔
1387
    n = Int(length(iter))::Int
117,700✔
1388
    i = lastindex(a)
116,721✔
1389
    sizehint!(a, length(a) + n; shrink=false)
116,721✔
1390
    for item in iter
145,157✔
1391
        push!(a, item)
52,592✔
1392
    end
61,910✔
1393
    a
116,704✔
1394
end
1395
function _append!(a::AbstractVector, ::IteratorSize, iter)
67,556✔
1396
    for item in iter
94,736✔
1397
        push!(a, item)
42,039✔
1398
    end
42,199✔
1399
    a
67,557✔
1400
end
1401

1402
"""
1403
    prepend!(a::Vector, collections...) -> collection
1404

1405
Insert the elements of each `collections` to the beginning of `a`.
1406

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

1410
!!! compat "Julia 1.6"
1411
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1412

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

1421
julia> prepend!([6], [1, 2], [3, 4, 5])
1422
6-element Vector{Int64}:
1423
 1
1424
 2
1425
 3
1426
 4
1427
 5
1428
 6
1429
```
1430
"""
1431
function prepend! end
1432

1433
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
2,153✔
1434
    items isa Tuple && (items = map(x -> convert(T, x), items))
1,651✔
1435
    n = length(items)
3,723✔
1436
    _growbeg!(a, n)
7,137✔
1437
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1438
    # just the last n elements instead of all of them from the first
1439
    copyto!(a, 1, items, lastindex(items)-n+1, n)
7,131✔
1440
    return a
3,723✔
1441
end
1442

1443
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
231✔
1444
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
16✔
1445
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
7✔
1446

1447
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
211✔
1448
    @_terminates_locally_meta
212✔
1449
    require_one_based_indexing(a)
212✔
1450
    n = Int(length(iter))::Int
212✔
1451
    sizehint!(a, length(a) + n; first=true, shrink=false)
212✔
1452
    n = 0
212✔
1453
    for item in iter
213✔
1454
        n += 1
373✔
1455
        pushfirst!(a, item)
374✔
1456
    end
369✔
1457
    reverse!(a, 1, n)
206✔
1458
    a
206✔
1459
end
1460
function _prepend!(a::Vector, ::IteratorSize, iter)
3✔
1461
    n = 0
3✔
1462
    for item in iter
5✔
1463
        n += 1
8✔
1464
        pushfirst!(a, item)
11✔
1465
    end
13✔
1466
    reverse!(a, 1, n)
2✔
1467
    a
2✔
1468
end
1469

1470
"""
1471
    resize!(a::Vector, n::Integer) -> a
1472

1473
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1474
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1475
guaranteed to be initialized.
1476

1477
# Examples
1478
```jldoctest
1479
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1480
3-element Vector{Int64}:
1481
 6
1482
 5
1483
 4
1484

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

1487
julia> length(a)
1488
8
1489

1490
julia> a[1:6]
1491
6-element Vector{Int64}:
1492
 6
1493
 5
1494
 4
1495
 3
1496
 2
1497
 1
1498
```
1499
"""
1500
function resize!(a::Vector, nl_::Integer)
702,144✔
1501
    nl = Int(nl_)::Int
12,274,201✔
1502
    l = length(a)
12,276,239✔
1503
    if nl > l
12,276,250✔
1504
        _growend!(a, nl-l)
4,272,638✔
1505
    elseif nl != l
8,003,703✔
1506
        if nl < 0
1,776,526✔
1507
            _throw_argerror("new length must be ≥ 0")
×
1508
        end
1509
        _deleteend!(a, l-nl)
1,776,533✔
1510
    end
1511
    return a
12,276,178✔
1512
end
1513

1514
"""
1515
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1516

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

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

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

1530
See also [`resize!`](@ref).
1531

1532
# Notes on the performance model
1533

1534
For types that support `sizehint!`,
1535

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

1540
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1541
   `Base`.
1542

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

1545
!!! compat "Julia 1.11"
1546
    The `shrink` and `first` arguments were added in Julia 1.11.
1547
"""
1548
function sizehint! end
1549

1550
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
1,591,954✔
1551
    len = length(a)
788,449✔
1552
    ref = a.ref
788,449✔
1553
    mem = ref.mem
788,449✔
1554
    memlen = length(mem)
788,449✔
1555
    sz = max(Int(sz), len)
788,449✔
1556
    inc = sz - len
788,449✔
1557
    if sz <= memlen
788,449✔
1558
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1559
        if !shrink || memlen - sz <= div(memlen, 8)
1,439,652✔
1560
            return a
111,700✔
1561
        end
1562
        newmem = array_new_memory(mem, sz)
665,303✔
1563
        if first
663,815✔
1564
            newref = memoryref(newmem, inc + 1)
×
1565
        else
1566
            newref = memoryref(newmem)
663,815✔
1567
        end
1568
        unsafe_copyto!(newref, ref, len)
666,385✔
1569
        setfield!(a, :ref, newref)
663,815✔
1570
    elseif first
12,936✔
1571
        _growbeg!(a, inc)
×
1572
        newref = getfield(a, :ref)
×
1573
        newref = memoryref(newref, inc + 1)
×
1574
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
×
1575
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
×
1576
    else # last
1577
        _growend!(a, inc)
12,936✔
1578
        setfield!(a, :size, (len,)) # undo the size change from _growend!
12,936✔
1579
    end
1580
    a
676,751✔
1581
end
1582

1583
# Fall-back implementation for non-shrinkable collections
1584
# avoid defining this the normal way to avoid avoid infinite recursion
1585
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
1586
    get(kwargs, :first, false)::Bool
17,105✔
1587
    get(kwargs, :shrink, true)::Bool
17,105✔
1588
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
17,105✔
1589
    sizehint!(a, sz)
17,105✔
1590
end
1591

1592
"""
1593
    pop!(collection) -> item
1594

1595
Remove an item in `collection` and return it. If `collection` is an
1596
ordered container, the last item is returned; for unordered containers,
1597
an arbitrary element is returned.
1598

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

1601
# Examples
1602
```jldoctest
1603
julia> A=[1, 2, 3]
1604
3-element Vector{Int64}:
1605
 1
1606
 2
1607
 3
1608

1609
julia> pop!(A)
1610
3
1611

1612
julia> A
1613
2-element Vector{Int64}:
1614
 1
1615
 2
1616

1617
julia> S = Set([1, 2])
1618
Set{Int64} with 2 elements:
1619
  2
1620
  1
1621

1622
julia> pop!(S)
1623
2
1624

1625
julia> S
1626
Set{Int64} with 1 element:
1627
  1
1628

1629
julia> pop!(Dict(1=>2))
1630
1 => 2
1631
```
1632
"""
1633
function pop!(a::Vector)
136,681✔
1634
    if isempty(a)
7,941,774✔
1635
        _throw_argerror("array must be non-empty")
×
1636
    end
1637
    item = a[end]
7,941,776✔
1638
    _deleteend!(a, 1)
7,941,766✔
1639
    return item
7,941,761✔
1640
end
1641

1642
"""
1643
    popat!(a::Vector, i::Integer, [default])
1644

1645
Remove the item at the given `i` and return it. Subsequent items
1646
are shifted to fill the resulting gap.
1647
When `i` is not a valid index for `a`, return `default`, or throw an error if
1648
`default` is not specified.
1649

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

1652
!!! compat "Julia 1.5"
1653
    This function is available as of Julia 1.5.
1654

1655
# Examples
1656
```jldoctest
1657
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1658
3
1659

1660
julia> a
1661
3-element Vector{Int64}:
1662
 4
1663
 2
1664
 1
1665

1666
julia> popat!(a, 4, missing)
1667
missing
1668

1669
julia> popat!(a, 4)
1670
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1671
[...]
1672
```
1673
"""
1674
function popat!(a::Vector, i::Integer)
4✔
1675
    @_propagate_inbounds_meta
7✔
1676
    x = a[i]
10✔
1677
    _deleteat!(a, i, 1)
4✔
1678
    x
4✔
1679
end
1680

1681
function popat!(a::Vector, i::Integer, default)
2✔
1682
    if 1 <= i <= length(a)
2✔
1683
        x = @inbounds a[i]
1✔
1684
        _deleteat!(a, i, 1)
1✔
1685
        x
1✔
1686
    else
1687
        default
1✔
1688
    end
1689
end
1690

1691
"""
1692
    pushfirst!(collection, items...) -> collection
1693

1694
Insert one or more `items` at the beginning of `collection`.
1695

1696
This function is called `unshift` in many other programming languages.
1697

1698
# Examples
1699
```jldoctest
1700
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1701
6-element Vector{Int64}:
1702
 5
1703
 6
1704
 1
1705
 2
1706
 3
1707
 4
1708
```
1709
"""
1710
function pushfirst!(a::Vector{T}, item) where T
338✔
1711
    @inline
6,012,835✔
1712
    item = item isa T ? item : convert(T, item)::T
6,012,838✔
1713
    return _pushfirst!(a, item)
6,021,128✔
1714
end
1715
function _pushfirst!(a::Vector{T}, item::T) where T
×
1716
    _growbeg!(a, 1)
6,021,385✔
1717
    @_safeindex a[1] = item
6,018,046✔
1718
    return a
6,018,046✔
1719
end
1720

1721
# specialize and optimize the single argument case
1722
function pushfirst!(a::Vector{Any}, @nospecialize x)
66✔
1723
    _growbeg!(a, 1)
407,488✔
1724
    @_safeindex a[1] = x
400,671✔
1725
    return a
400,671✔
1726
end
1727
function pushfirst!(a::Vector{Any}, @nospecialize x...)
2✔
1728
    @_terminates_locally_meta
2✔
1729
    na = length(a)
2✔
1730
    nx = length(x)
2✔
1731
    _growbeg!(a, nx)
4✔
1732
    @_safeindex for i = 1:nx
2✔
1733
        a[i] = x[i]
6✔
1734
    end
10✔
1735
    return a
2✔
1736
end
1737

1738
"""
1739
    popfirst!(collection) -> item
1740

1741
Remove the first `item` from `collection`.
1742

1743
This function is called `shift` in many other programming languages.
1744

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

1747
# Examples
1748
```jldoctest
1749
julia> A = [1, 2, 3, 4, 5, 6]
1750
6-element Vector{Int64}:
1751
 1
1752
 2
1753
 3
1754
 4
1755
 5
1756
 6
1757

1758
julia> popfirst!(A)
1759
1
1760

1761
julia> A
1762
5-element Vector{Int64}:
1763
 2
1764
 3
1765
 4
1766
 5
1767
 6
1768
```
1769
"""
1770
function popfirst!(a::Vector)
598✔
1771
    if isempty(a)
9,094,963✔
1772
        _throw_argerror("array must be non-empty")
×
1773
    end
1774
    item = a[1]
9,094,957✔
1775
    _deletebeg!(a, 1)
9,094,955✔
1776
    return item
9,094,952✔
1777
end
1778

1779
"""
1780
    insert!(a::Vector, index::Integer, item)
1781

1782
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1783
the resulting `a`.
1784

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

1787
# Examples
1788
```jldoctest
1789
julia> insert!(Any[1:6;], 3, "here")
1790
7-element Vector{Any}:
1791
 1
1792
 2
1793
  "here"
1794
 3
1795
 4
1796
 5
1797
 6
1798
```
1799
"""
1800
function insert!(a::Array{T,1}, i::Integer, item) where T
326✔
1801
    @_propagate_inbounds_meta
592,227✔
1802
    item = item isa T ? item : convert(T, item)::T
592,230✔
1803
    return _insert!(a, i, item)
648,442✔
1804
end
1805
function _insert!(a::Array{T,1}, i::Integer, item::T) where T
1806
    @_noub_meta
592,193✔
1807
    # Throw convert error before changing the shape of the array
1808
    _growat!(a, i, 1)
648,434✔
1809
    # :noub, because _growat! already did bound check
1810
    @inbounds a[i] = item
648,411✔
1811
    return a
648,295✔
1812
end
1813

1814
"""
1815
    deleteat!(a::Vector, i::Integer)
1816

1817
Remove the item at the given `i` and return the modified `a`. Subsequent items
1818
are shifted to fill the resulting gap.
1819

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

1822
# Examples
1823
```jldoctest
1824
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1825
5-element Vector{Int64}:
1826
 6
1827
 4
1828
 3
1829
 2
1830
 1
1831
```
1832
"""
1833
function deleteat!(a::Vector, i::Integer)
269✔
1834
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
46,238✔
1835
    _deleteat!(a, i, 1)
46,719✔
1836
    return a
46,238✔
1837
end
1838

1839
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
34,093✔
1840
    if eltype(r) === Bool
109,175✔
1841
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1842
    else
1843
        n = length(a)
109,168✔
1844
        f = first(r)
109,176✔
1845
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
109,166✔
1846
        isempty(r) || _deleteat!(a, f, length(r))
214,812✔
1847
        return a
109,297✔
1848
    end
1849
end
1850

1851
"""
1852
    deleteat!(a::Vector, inds)
1853

1854
Remove the items at the indices given by `inds`, and return the modified `a`.
1855
Subsequent items are shifted to fill the resulting gap.
1856

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

1860
# Examples
1861
```jldoctest
1862
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1863
3-element Vector{Int64}:
1864
 5
1865
 3
1866
 1
1867

1868
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1869
3-element Vector{Int64}:
1870
 5
1871
 3
1872
 1
1873

1874
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1875
ERROR: ArgumentError: indices must be unique and sorted
1876
Stacktrace:
1877
[...]
1878
```
1879
"""
1880
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1881
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
36,219✔
1882

1883
struct Nowhere; end
82✔
1884
push!(::Nowhere, _) = nothing
1,491,924✔
1885
_growend!(::Nowhere, _) = nothing
×
1886

1887
function _push_deleted!(dltd, a::Vector, ind)
1888
    @_propagate_inbounds_meta
1,491,926✔
1889
    if isassigned(a, ind)
1,491,926✔
1890
        push!(dltd, a[ind])
1,491,939✔
1891
    else
1892
        _growend!(dltd, 1)
×
1893
    end
1894
end
1895

1896
function _copy_item!(a::Vector, p, q)
1897
    @_propagate_inbounds_meta
4,378,851✔
1898
    if isassigned(a, q)
4,378,851✔
1899
        a[p] = a[q]
4,378,851✔
1900
    else
1901
        _unsetindex!(a, p)
×
1902
    end
1903
end
1904

1905
function _deleteat!(a::Vector, inds, dltd=Nowhere())
35,796✔
1906
    n = length(a)
72,034✔
1907
    y = iterate(inds)
35,806✔
1908
    y === nothing && return a
35,796✔
1909
    (p, s) = y
35,482✔
1910
    checkbounds(a, p)
35,486✔
1911
    @inbounds _push_deleted!(dltd, a, p)
35,482✔
1912
    q = p+1
35,478✔
1913
    while true
1,491,926✔
1914
        y = iterate(inds, s)
1,491,937✔
1915
        y === nothing && break
1,491,926✔
1916
        (i,s) = y
1,456,450✔
1917
        if !(q <= i <= n)
1,456,450✔
1918
            if i < q
2✔
1919
                _throw_argerror("indices must be unique and sorted")
1✔
1920
            else
1921
                throw(BoundsError())
1✔
1922
            end
1923
        end
1924
        while q < i
2,877,941✔
1925
            @inbounds _copy_item!(a, p, q)
1,421,493✔
1926
            p += 1; q += 1
1,421,493✔
1927
        end
1,421,493✔
1928
        @inbounds _push_deleted!(dltd, a, i)
1,456,457✔
1929
        q = i+1
1,456,448✔
1930
    end
1,456,448✔
1931
    while q <= n
2,950,640✔
1932
        @inbounds _copy_item!(a, p, q)
2,915,164✔
1933
        p += 1; q += 1
2,915,164✔
1934
    end
2,915,164✔
1935
    _deleteend!(a, n-p+1)
1,491,924✔
1936
    return a
35,476✔
1937
end
1938

1939
# Simpler and more efficient version for logical indexing
1940
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1941
    n = length(a)
4,029✔
1942
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1943
    p = 1
4,024✔
1944
    for (q, i) in enumerate(inds)
8,047✔
1945
        @inbounds _copy_item!(a, p, q)
42,194✔
1946
        p += !i
42,194✔
1947
    end
80,365✔
1948
    _deleteend!(a, n-p+1)
21,353✔
1949
    return a
4,024✔
1950
end
1951

1952
const _default_splice = []
1953

1954
"""
1955
    splice!(a::Vector, index::Integer, [replacement]) -> item
1956

1957
Remove the item at the given index, and return the removed item.
1958
Subsequent items are shifted left to fill the resulting gap.
1959
If specified, replacement values from an ordered
1960
collection will be spliced in place of the removed item.
1961

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

1964
# Examples
1965
```jldoctest
1966
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1967
2
1968

1969
julia> A
1970
5-element Vector{Int64}:
1971
 6
1972
 5
1973
 4
1974
 3
1975
 1
1976

1977
julia> splice!(A, 5, -1)
1978
1
1979

1980
julia> A
1981
5-element Vector{Int64}:
1982
  6
1983
  5
1984
  4
1985
  3
1986
 -1
1987

1988
julia> splice!(A, 1, [-1, -2, -3])
1989
6
1990

1991
julia> A
1992
7-element Vector{Int64}:
1993
 -1
1994
 -2
1995
 -3
1996
  5
1997
  4
1998
  3
1999
 -1
2000
```
2001

2002
To insert `replacement` before an index `n` without removing any items, use
2003
`splice!(collection, n:n-1, replacement)`.
2004
"""
2005
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,692✔
2006
    v = a[i]
3,708✔
2007
    m = length(ins)
3,416✔
2008
    if m == 0
3,416✔
2009
        _deleteat!(a, i, 1)
541✔
2010
    elseif m == 1
2,875✔
2011
        a[i] = only(ins)
265✔
2012
    else
2013
        _growat!(a, i, m-1)
2,610✔
2014
        k = 1
2,610✔
2015
        for x in ins
2,610✔
2016
            a[i+k-1] = x
333,419✔
2017
            k += 1
333,419✔
2018
        end
333,419✔
2019
    end
2020
    return v
3,416✔
2021
end
2022

2023
"""
2024
    splice!(a::Vector, indices, [replacement]) -> items
2025

2026
Remove items at specified indices, and return a collection containing
2027
the removed items.
2028
Subsequent items are shifted left to fill the resulting gaps.
2029
If specified, replacement values from an ordered collection will be spliced in
2030
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
2031

2032
To insert `replacement` before an index `n` without removing any items, use
2033
`splice!(collection, n:n-1, replacement)`.
2034

2035
$(_DOCS_ALIASING_WARNING)
2036

2037
!!! compat "Julia 1.5"
2038
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
2039

2040
!!! compat "Julia 1.8"
2041
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
2042

2043
# Examples
2044
```jldoctest
2045
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
2046
Int64[]
2047

2048
julia> A
2049
8-element Vector{Int64}:
2050
 -1
2051
 -2
2052
 -3
2053
  2
2054
  5
2055
  4
2056
  3
2057
 -1
2058
```
2059
"""
2060
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
171,426✔
2061
    v = a[r]
241,656✔
2062
    m = length(ins)
137,488✔
2063
    if m == 0
137,488✔
2064
        deleteat!(a, r)
74,059✔
2065
        return v
37,090✔
2066
    end
2067

2068
    n = length(a)
100,398✔
2069
    f = first(r)
100,398✔
2070
    l = last(r)
100,398✔
2071
    d = length(r)
100,398✔
2072

2073
    if m < d
100,398✔
2074
        delta = d - m
12,582✔
2075
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
18,972✔
2076
    elseif m > d
87,816✔
2077
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
87,701✔
2078
    end
2079

2080
    k = 1
100,398✔
2081
    for x in ins
111,904✔
2082
        a[f+k-1] = x
4,235,500✔
2083
        k += 1
4,235,500✔
2084
    end
5,647,296✔
2085
    return v
100,398✔
2086
end
2087

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

2090
function empty!(a::Vector)
157✔
2091
    _deleteend!(a, length(a))
706,973✔
2092
    return a
584,284✔
2093
end
2094

2095
# use memcmp for cmp on byte arrays
2096
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
×
2097
    aref = a.ref
×
2098
    bref = b.ref
×
2099
    ta = @_gc_preserve_begin aref
×
2100
    tb = @_gc_preserve_begin bref
×
2101
    pa = unsafe_convert(Ptr{Cvoid}, aref)
×
2102
    pb = unsafe_convert(Ptr{Cvoid}, bref)
×
2103
    c = memcmp(pa, pb, min(length(a),length(b)))
×
2104
    @_gc_preserve_end ta
×
2105
    @_gc_preserve_end tb
×
2106
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
×
2107
end
2108

2109
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2110
# use memcmp for == on bit integer types
2111
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,546✔
2112
    if size(a) == size(b)
4,564✔
2113
        aref = a.ref
2,313✔
2114
        bref = b.ref
2,313✔
2115
        ta = @_gc_preserve_begin aref
2,313✔
2116
        tb = @_gc_preserve_begin bref
2,313✔
2117
        pa = unsafe_convert(Ptr{Cvoid}, aref)
2,313✔
2118
        pb = unsafe_convert(Ptr{Cvoid}, bref)
2,313✔
2119
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
2,313✔
2120
        @_gc_preserve_end ta
2,313✔
2121
        @_gc_preserve_end tb
2,313✔
2122
        return c == 0
2,313✔
2123
    else
2124
        return false
×
2125
    end
2126
end
2127

2128
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
87✔
2129
    len = length(a)
9,183✔
2130
    if len == length(b)
9,183✔
2131
        aref = a.ref
9,021✔
2132
        bref = b.ref
9,021✔
2133
        ta = @_gc_preserve_begin aref
9,021✔
2134
        tb = @_gc_preserve_begin bref
9,021✔
2135
        T = eltype(Arr)
90✔
2136
        pa = unsafe_convert(Ptr{T}, aref)
9,021✔
2137
        pb = unsafe_convert(Ptr{T}, bref)
9,021✔
2138
        c = memcmp(pa, pb, sizeof(T) * len)
9,021✔
2139
        @_gc_preserve_end ta
9,021✔
2140
        @_gc_preserve_end tb
9,021✔
2141
        return c == 0
9,021✔
2142
    else
2143
        return false
162✔
2144
    end
2145
end
2146

2147
"""
2148
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2149

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

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

2163
julia> reverse(A)
2164
5-element Vector{Int64}:
2165
 5
2166
 4
2167
 3
2168
 2
2169
 1
2170

2171
julia> reverse(A, 1, 4)
2172
5-element Vector{Int64}:
2173
 4
2174
 3
2175
 2
2176
 1
2177
 5
2178

2179
julia> reverse(A, 3, 5)
2180
5-element Vector{Int64}:
2181
 1
2182
 2
2183
 5
2184
 4
2185
 3
2186
```
2187
"""
2188
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
2,347✔
2189
    s, n = Int(start), Int(stop)
2,347✔
2190
    B = similar(A)
2,347✔
2191
    for i = firstindex(A):s-1
2,348✔
2192
        B[i] = A[i]
1,677✔
2193
    end
3,066✔
2194
    for i = s:n
3,585✔
2195
        B[i] = A[n+s-i]
171,869✔
2196
    end
341,397✔
2197
    for i = n+1:lastindex(A)
3,172✔
2198
        B[i] = A[i]
1,680✔
2199
    end
3,072✔
2200
    return B
2,347✔
2201
end
2202

2203
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2204
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2205
    @eval begin
2206
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
1,972,943✔
2207
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
12,710✔
2208
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2209
        function $_f(A::AbstractVector, dim::Integer)
2210
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
2211
            return $_f(A, :)
4✔
2212
        end
2213
    end
2214
end
2215

2216
function reverseind(a::AbstractVector, i::Integer)
3✔
2217
    li = LinearIndices(a)
3✔
2218
    first(li) + last(li) - i
3✔
2219
end
2220

2221
# This implementation of `midpoint` is performance-optimized but safe
2222
# only if `lo <= hi`.
2223
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
333,219✔
2224
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2225

2226
"""
2227
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2228

2229
In-place version of [`reverse`](@ref).
2230

2231
# Examples
2232
```jldoctest
2233
julia> A = Vector(1:5)
2234
5-element Vector{Int64}:
2235
 1
2236
 2
2237
 3
2238
 4
2239
 5
2240

2241
julia> reverse!(A);
2242

2243
julia> A
2244
5-element Vector{Int64}:
2245
 5
2246
 4
2247
 3
2248
 2
2249
 1
2250
```
2251
"""
2252
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
291,633✔
2253
    s, n = Int(start), Int(stop)
1,485,799✔
2254
    if n > s # non-empty and non-trivial
291,630✔
2255
        liv = LinearIndices(v)
84,930✔
2256
        if !(first(liv) ≤ s ≤ last(liv))
84,930✔
2257
            throw(BoundsError(v, s))
2✔
2258
        elseif !(first(liv) ≤ n ≤ last(liv))
84,928✔
2259
            throw(BoundsError(v, n))
×
2260
        end
2261
        r = n
84,928✔
2262
        @inbounds for i in s:midpoint(s, n-1)
156,315✔
2263
            v[i], v[r] = v[r], v[i]
7,793,993✔
2264
            r -= 1
7,793,993✔
2265
        end
15,503,058✔
2266
    end
2267
    return v
291,628✔
2268
end
2269

2270
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2271

2272
vcat() = Vector{Any}()
12,270✔
2273
hcat() = Vector{Any}()
1✔
2274

2275
function hcat(V::Vector{T}...) where T
63✔
2276
    height = length(V[1])
570✔
2277
    for j = 2:length(V)
570✔
2278
        if length(V[j]) != height
636✔
2279
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2280
        end
2281
    end
733✔
2282
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
569✔
2283
end
2284
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2285

2286
function vcat(arrays::Vector{T}...) where T
34,586✔
2287
    n = 0
34,586✔
2288
    for a in arrays
34,586✔
2289
        n += length(a)
2,069,343✔
2290
    end
2,103,892✔
2291
    arr = Vector{T}(undef, n)
34,586✔
2292
    nd = 1
34,586✔
2293
    for a in arrays
34,586✔
2294
        na = length(a)
2,069,343✔
2295
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,069,343✔
2296
        unsafe_copyto!(arr, nd, a, 1, na)
4,138,532✔
2297
        nd += na
2,069,343✔
2298
    end
2,103,892✔
2299
    return arr
34,586✔
2300
end
2301
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
36✔
2302

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

2305
## find ##
2306

2307
"""
2308
    findnext(A, i)
2309

2310
Find the next index after or including `i` of a `true` element of `A`,
2311
or `nothing` if not found.
2312

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

2316
# Examples
2317
```jldoctest
2318
julia> A = [false, false, true, false]
2319
4-element Vector{Bool}:
2320
 0
2321
 0
2322
 1
2323
 0
2324

2325
julia> findnext(A, 1)
2326
3
2327

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

2330
julia> A = [false false; true false]
2331
2×2 Matrix{Bool}:
2332
 0  0
2333
 1  0
2334

2335
julia> findnext(A, CartesianIndex(1, 1))
2336
CartesianIndex(2, 1)
2337
```
2338
"""
2339
findnext(A, start) = findnext(identity, A, start)
77,382✔
2340

2341
"""
2342
    findfirst(A)
2343

2344
Return the index or key of the first `true` value in `A`.
2345
Return `nothing` if no such value is found.
2346
To search for other kinds of values, pass a predicate as the first argument.
2347

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

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

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

2362
julia> findfirst(A)
2363
3
2364

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

2367
julia> A = [false false; true false]
2368
2×2 Matrix{Bool}:
2369
 0  0
2370
 1  0
2371

2372
julia> findfirst(A)
2373
CartesianIndex(2, 1)
2374
```
2375
"""
2376
findfirst(A) = findfirst(identity, A)
2✔
2377

2378
# Needed for bootstrap, and allows defining only an optimized findnext method
2379
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
47,093✔
2380

2381
"""
2382
    findnext(predicate::Function, A, i)
2383

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

2389
Indices are of the same type as those returned by [`keys(A)`](@ref)
2390
and [`pairs(A)`](@ref).
2391

2392
# Examples
2393
```jldoctest
2394
julia> A = [1, 4, 2, 2];
2395

2396
julia> findnext(isodd, A, 1)
2397
1
2398

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

2401
julia> A = [1 4; 2 2];
2402

2403
julia> findnext(isodd, A, CartesianIndex(1, 1))
2404
CartesianIndex(1, 1)
2405

2406
julia> findnext(isspace, "a b c", 3)
2407
4
2408
```
2409
"""
2410
function findnext(testf::Function, A, start)
10,086✔
2411
    i = oftype(first(keys(A)), start)
189,546✔
2412
    l = last(keys(A))
250,354✔
2413
    i > l && return nothing
250,354✔
2414
    while true
682,737✔
2415
        testf(A[i]) && return i
684,710✔
2416
        i == l && break
623,588✔
2417
        # nextind(A, l) can throw/overflow
2418
        i = nextind(A, i)
594,895✔
2419
    end
594,876✔
2420
    return nothing
28,688✔
2421
end
2422

2423
"""
2424
    findfirst(predicate::Function, A)
2425

2426
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2427
Return `nothing` if there is no such element.
2428

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

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

2441
julia> findfirst(iseven, A)
2442
2
2443

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

2446
julia> findfirst(isequal(4), A)
2447
2
2448

2449
julia> A = [1 4; 2 2]
2450
2×2 Matrix{Int64}:
2451
 1  4
2452
 2  2
2453

2454
julia> findfirst(iseven, A)
2455
CartesianIndex(2, 1)
2456
```
2457
"""
2458
function findfirst(testf::Function, A)
15✔
2459
    for (i, a) in pairs(A)
22✔
2460
        testf(a) && return i
14✔
2461
    end
11✔
2462
    return nothing
8✔
2463
end
2464

2465
# Needed for bootstrap, and allows defining only an optimized findnext method
2466
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
3,761,170✔
2467
    findnext(testf, A, first(keys(A)))
2468

2469
findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::OneTo) where {T<:Integer} =
6✔
2470
    1 <= p.x <= r.stop ? convert(keytype(r), p.x) : nothing
2471

2472
findfirst(::typeof(iszero), ::OneTo) = nothing
2✔
2473
findfirst(::typeof(isone), r::OneTo) = isempty(r) ? nothing : oneunit(keytype(r))
5✔
2474

2475
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::AbstractUnitRange{<:Integer}) where {T<:Integer}
6✔
2476
    first(r) <= p.x <= last(r) || return nothing
29✔
2477
    i1 = first(keys(r))
9✔
2478
    return i1 + oftype(i1, p.x - first(r))
9✔
2479
end
2480

2481
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
151✔
2482
    isempty(r) && return nothing
151✔
2483
    minimum(r) <= p.x <= maximum(r) || return nothing
192✔
2484
    d = p.x - first(r)
106✔
2485
    iszero(d % step(r)) || return nothing
142✔
2486
    return convert(keytype(r), d ÷ step(r) + 1)
70✔
2487
end
2488

2489
findfirst(::typeof(iszero), r::AbstractRange) = findfirst(==(zero(first(r))), r)
130✔
2490
findfirst(::typeof(isone), r::AbstractRange) = findfirst(==(one(first(r))), r)
3✔
2491

2492
"""
2493
    findprev(A, i)
2494

2495
Find the previous index before or including `i` of a `true` element of `A`,
2496
or `nothing` if not found.
2497

2498
Indices are of the same type as those returned by [`keys(A)`](@ref)
2499
and [`pairs(A)`](@ref).
2500

2501
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2502

2503
# Examples
2504
```jldoctest
2505
julia> A = [false, false, true, true]
2506
4-element Vector{Bool}:
2507
 0
2508
 0
2509
 1
2510
 1
2511

2512
julia> findprev(A, 3)
2513
3
2514

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

2517
julia> A = [false false; true true]
2518
2×2 Matrix{Bool}:
2519
 0  0
2520
 1  1
2521

2522
julia> findprev(A, CartesianIndex(2, 1))
2523
CartesianIndex(2, 1)
2524
```
2525
"""
2526
findprev(A, start) = findprev(identity, A, start)
8,326✔
2527

2528
"""
2529
    findlast(A)
2530

2531
Return the index or key of the last `true` value in `A`.
2532
Return `nothing` if there is no `true` value in `A`.
2533

2534
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2535
and [`pairs(A)`](@ref).
2536

2537
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2538

2539
# Examples
2540
```jldoctest
2541
julia> A = [true, false, true, false]
2542
4-element Vector{Bool}:
2543
 1
2544
 0
2545
 1
2546
 0
2547

2548
julia> findlast(A)
2549
3
2550

2551
julia> A = falses(2,2);
2552

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

2555
julia> A = [true false; true false]
2556
2×2 Matrix{Bool}:
2557
 1  0
2558
 1  0
2559

2560
julia> findlast(A)
2561
CartesianIndex(2, 1)
2562
```
2563
"""
2564
findlast(A) = findlast(identity, A)
24✔
2565

2566
# Needed for bootstrap, and allows defining only an optimized findprev method
2567
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
7✔
2568

2569
"""
2570
    findprev(predicate::Function, A, i)
2571

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

2577
Indices are of the same type as those returned by [`keys(A)`](@ref)
2578
and [`pairs(A)`](@ref).
2579

2580
# Examples
2581
```jldoctest
2582
julia> A = [4, 6, 1, 2]
2583
4-element Vector{Int64}:
2584
 4
2585
 6
2586
 1
2587
 2
2588

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

2591
julia> findprev(isodd, A, 3)
2592
3
2593

2594
julia> A = [4 6; 1 2]
2595
2×2 Matrix{Int64}:
2596
 4  6
2597
 1  2
2598

2599
julia> findprev(isodd, A, CartesianIndex(1, 2))
2600
CartesianIndex(2, 1)
2601

2602
julia> findprev(isspace, "a b c", 3)
2603
2
2604
```
2605
"""
2606
function findprev(testf::Function, A, start)
212✔
2607
    f = first(keys(A))
9,370✔
2608
    i = oftype(f, start)
9,381✔
2609
    i < f && return nothing
9,370✔
2610
    while true
152,868✔
2611
        testf(A[i]) && return i
152,872✔
2612
        i == f && break
143,663✔
2613
        # prevind(A, f) can throw/underflow
2614
        i = prevind(A, i)
143,526✔
2615
    end
143,498✔
2616
    return nothing
134✔
2617
end
2618

2619
"""
2620
    findlast(predicate::Function, A)
2621

2622
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2623
Return `nothing` if there is no such element.
2624

2625
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2626
and [`pairs(A)`](@ref).
2627

2628
# Examples
2629
```jldoctest
2630
julia> A = [1, 2, 3, 4]
2631
4-element Vector{Int64}:
2632
 1
2633
 2
2634
 3
2635
 4
2636

2637
julia> findlast(isodd, A)
2638
3
2639

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

2642
julia> A = [1 2; 3 4]
2643
2×2 Matrix{Int64}:
2644
 1  2
2645
 3  4
2646

2647
julia> findlast(isodd, A)
2648
CartesianIndex(2, 1)
2649
```
2650
"""
2651
function findlast(testf::Function, A)
3✔
2652
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2653
        testf(a) && return i
6✔
2654
    end
6✔
2655
    return nothing
2✔
2656
end
2657

2658
# Needed for bootstrap, and allows defining only an optimized findprev method
2659
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
15,171✔
2660
    findprev(testf, A, last(keys(A)))
2661

2662
# for monotonic ranges, there is a unique index corresponding to a value, so findfirst and findlast are identical
2663
function findlast(p::Union{Fix2{typeof(isequal),<:Integer},Fix2{typeof(==),<:Integer},typeof(iszero),typeof(isone)},
13✔
2664
        r::AbstractUnitRange{<:Integer})
2665
    findfirst(p, r)
14✔
2666
end
2667

2668
function findlast(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T},typeof(iszero),typeof(isone)},
9✔
2669
        r::StepRange{T,S}) where {T,S}
2670
    findfirst(p, r)
9✔
2671
end
2672

2673
"""
2674
    findall(f::Function, A)
2675

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

2679
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2680
and [`pairs(A)`](@ref).
2681

2682
# Examples
2683
```jldoctest
2684
julia> x = [1, 3, 4]
2685
3-element Vector{Int64}:
2686
 1
2687
 3
2688
 4
2689

2690
julia> findall(isodd, x)
2691
2-element Vector{Int64}:
2692
 1
2693
 2
2694

2695
julia> A = [1 2 0; 3 4 0]
2696
2×3 Matrix{Int64}:
2697
 1  2  0
2698
 3  4  0
2699
julia> findall(isodd, A)
2700
2-element Vector{CartesianIndex{2}}:
2701
 CartesianIndex(1, 1)
2702
 CartesianIndex(2, 1)
2703

2704
julia> findall(!iszero, A)
2705
4-element Vector{CartesianIndex{2}}:
2706
 CartesianIndex(1, 1)
2707
 CartesianIndex(2, 1)
2708
 CartesianIndex(1, 2)
2709
 CartesianIndex(2, 2)
2710

2711
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2712
Dict{Symbol, Int64} with 3 entries:
2713
  :A => 10
2714
  :B => -1
2715
  :C => 0
2716

2717
julia> findall(≥(0), d)
2718
2-element Vector{Symbol}:
2719
 :A
2720
 :C
2721

2722
```
2723
"""
2724
function findall(testf::Function, A)
36✔
2725
    gen = (first(p) for p in pairs(A) if testf(last(p)))
43✔
2726
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
43✔
2727
end
2728

2729
# Broadcasting is much faster for small testf, and computing
2730
# integer indices from logical index using findall has a negligible cost
2731
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
351✔
2732

2733
"""
2734
    findall(A)
2735

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

2740
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2741
and [`pairs(A)`](@ref).
2742

2743
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2744

2745
# Examples
2746
```jldoctest
2747
julia> A = [true, false, false, true]
2748
4-element Vector{Bool}:
2749
 1
2750
 0
2751
 0
2752
 1
2753

2754
julia> findall(A)
2755
2-element Vector{Int64}:
2756
 1
2757
 4
2758

2759
julia> A = [true false; false true]
2760
2×2 Matrix{Bool}:
2761
 1  0
2762
 0  1
2763

2764
julia> findall(A)
2765
2-element Vector{CartesianIndex{2}}:
2766
 CartesianIndex(1, 1)
2767
 CartesianIndex(2, 2)
2768

2769
julia> findall(falses(3))
2770
Int64[]
2771
```
2772
"""
2773
function findall(A)
4✔
2774
    collect(first(p) for p in pairs(A) if last(p))
4✔
2775
end
2776

2777
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2778
function findall(A::AbstractArray{Bool})
34✔
2779
    n = count(A)
3,668✔
2780
    I = Vector{eltype(keys(A))}(undef, n)
3,663✔
2781
    cnt = 1
3,663✔
2782
    for (i,a) in pairs(A)
7,318✔
2783
        if a
206,778✔
2784
            I[cnt] = i
128,790✔
2785
            cnt += 1
128,790✔
2786
        end
2787
    end
409,898✔
2788
    I
3,663✔
2789
end
2790

2791
findall(x::Bool) = x ? [1] : Vector{Int}()
×
2792
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2793
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2794

2795
# similar to Matlab's ismember
2796
"""
2797
    indexin(a, b)
2798

2799
Return an array containing the first index in `b` for
2800
each value in `a` that is a member of `b`. The output
2801
array contains `nothing` wherever `a` is not a member of `b`.
2802

2803
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2804

2805
# Examples
2806
```jldoctest
2807
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2808

2809
julia> b = ['a', 'b', 'c'];
2810

2811
julia> indexin(a, b)
2812
6-element Vector{Union{Nothing, Int64}}:
2813
 1
2814
 2
2815
 3
2816
 2
2817
  nothing
2818
 1
2819

2820
julia> indexin(b, a)
2821
3-element Vector{Union{Nothing, Int64}}:
2822
 1
2823
 2
2824
 3
2825
```
2826
"""
2827
function indexin(a, b::AbstractArray)
7✔
2828
    inds = keys(b)
7✔
2829
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2830
    for (val, ind) in zip(b, inds)
14✔
2831
        get!(bdict, val, ind)
30✔
2832
    end
53✔
2833
    return Union{eltype(inds), Nothing}[
7✔
2834
        get(bdict, i, nothing) for i in a
2835
    ]
2836
end
2837

2838
function _findin(a::Union{AbstractArray, Tuple}, b::AbstractSet)
375✔
2839
    ind  = Vector{eltype(keys(a))}()
561✔
2840
    @inbounds for (i,ai) in pairs(a)
606✔
2841
        ai in b && push!(ind, i)
90,563✔
2842
    end
180,565✔
2843
    ind
375✔
2844
end
2845
_findin(a::Union{AbstractArray, Tuple}, b) = _findin(a, Set(b))
375✔
2846

2847
# If two collections are already sorted, _findin can be computed with
2848
# a single traversal of the two collections. This is much faster than
2849
# using a hash table (although it has the same complexity).
2850
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
9✔
2851
    viter, witer = keys(v), eachindex(w)
9✔
2852
    out  = eltype(viter)[]
9✔
2853
    vy, wy = iterate(viter), iterate(witer)
11✔
2854
    if vy === nothing || wy === nothing
17✔
2855
        return out
2✔
2856
    end
2857
    viteri, i = vy
7✔
2858
    witerj, j = wy
7✔
2859
    @inbounds begin
7✔
2860
        vi, wj = v[viteri], w[witerj]
7✔
2861
        while true
54✔
2862
            if isless(vi, wj)
56✔
2863
                vy = iterate(viter, i)
25✔
2864
                if vy === nothing
14✔
2865
                    break
2✔
2866
                end
2867
                viteri, i = vy
12✔
2868
                vi        = v[viteri]
12✔
2869
            elseif isless(wj, vi)
40✔
2870
                wy = iterate(witer, j)
44✔
2871
                if wy === nothing
24✔
2872
                    break
4✔
2873
                end
2874
                witerj, j = wy
20✔
2875
                wj        = w[witerj]
20✔
2876
            else
2877
                push!(out, viteri)
16✔
2878
                vy = iterate(viter, i)
25✔
2879
                if vy === nothing
16✔
2880
                    break
1✔
2881
                end
2882
                # We only increment the v iterator because v can have
2883
                # repeated matches to a single value in w
2884
                viteri, i = vy
15✔
2885
                vi        = v[viteri]
15✔
2886
            end
2887
        end
47✔
2888
    end
2889
    return out
7✔
2890
end
2891

2892
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2893
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2894
        return _sortedfindin(x, pred.x)
9✔
2895
    else
2896
        return _findin(x, pred.x)
6✔
2897
    end
2898
end
2899
# issorted fails for some element types so the method above has to be restricted
2900
# to element with isless/< defined.
2901
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
373✔
2902
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2903

2904
# Copying subregions
2905
function indcopy(sz::Dims, I::Vector)
1✔
2906
    n = length(I)
1✔
2907
    s = sz[n]
1✔
2908
    for i = n+1:length(sz)
2✔
2909
        s *= sz[i]
×
2910
    end
×
2911
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2912
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2913
    dst, src
1✔
2914
end
2915

2916
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2917
    n = length(I)
1✔
2918
    s = sz[n]
1✔
2919
    for i = n+1:length(sz)
1✔
2920
        s *= sz[i]
×
2921
    end
×
2922
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2923
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2924
    dst, src
1✔
2925
end
2926

2927
## Filter ##
2928

2929
"""
2930
    filter(f, a)
2931

2932
Return a copy of collection `a`, removing elements for which `f` is `false`.
2933
The function `f` is passed one argument.
2934

2935
!!! compat "Julia 1.4"
2936
    Support for `a` as a tuple requires at least Julia 1.4.
2937

2938
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2939

2940
# Examples
2941
```jldoctest
2942
julia> a = 1:10
2943
1:10
2944

2945
julia> filter(isodd, a)
2946
5-element Vector{Int64}:
2947
 1
2948
 3
2949
 5
2950
 7
2951
 9
2952
```
2953
"""
2954
function filter(f, a::Array{T, N}) where {T, N}
2,421✔
2955
    j = 1
2,421✔
2956
    b = Vector{T}(undef, length(a))
2,421✔
2957
    for ai in a
2,421✔
2958
        @inbounds b[j] = ai
180,590✔
2959
        j = ifelse(f(ai)::Bool, j+1, j)
181,707✔
2960
    end
180,590✔
2961
    resize!(b, j-1)
2,421✔
2962
    sizehint!(b, length(b))
2,421✔
2963
    b
2,421✔
2964
end
2965

2966
function filter(f, a::AbstractArray)
82✔
2967
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
82✔
2968

2969
    j = 1
82✔
2970
    idxs = Vector{Int}(undef, length(a))
85✔
2971
    for idx in eachindex(a)
85✔
2972
        @inbounds idxs[j] = idx
77,742✔
2973
        ai = @inbounds a[idx]
77,742✔
2974
        j = ifelse(f(ai)::Bool, j+1, j)
79,275✔
2975
    end
155,403✔
2976
    resize!(idxs, j-1)
81✔
2977
    res = a[idxs]
81✔
2978
    empty!(idxs)
3,215✔
2979
    sizehint!(idxs, 0)
81✔
2980
    return res
81✔
2981
end
2982

2983
"""
2984
    filter!(f, a)
2985

2986
Update collection `a`, removing elements for which `f` is `false`.
2987
The function `f` is passed one argument.
2988

2989
# Examples
2990
```jldoctest
2991
julia> filter!(isodd, Vector(1:10))
2992
5-element Vector{Int64}:
2993
 1
2994
 3
2995
 5
2996
 7
2997
 9
2998
```
2999
"""
3000
function filter!(f, a::AbstractVector)
1,059,555✔
3001
    j = firstindex(a)
1,059,886✔
3002
    for ai in a
1,059,853✔
3003
        @inbounds a[j] = ai
4,324,138✔
3004
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
4,512,161✔
3005
    end
4,324,683✔
3006
    j > lastindex(a) && return a
1,059,906✔
3007
    if a isa Vector
662,207✔
3008
        resize!(a, j-1)
662,206✔
3009
        sizehint!(a, j-1)
662,206✔
3010
    else
3011
        deleteat!(a, j:lastindex(a))
1✔
3012
    end
3013
    return a
662,209✔
3014
end
3015

3016
"""
3017
    filter(f)
3018

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

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

3025
# Examples
3026
```jldoctest
3027
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
3028
(1, 2, 4, 6)
3029

3030
julia> map(filter(iseven), [1:3, 2:4, 3:5])
3031
3-element Vector{Vector{Int64}}:
3032
 [2]
3033
 [2, 4]
3034
 [4]
3035
```
3036
!!! compat "Julia 1.9"
3037
    This method requires at least Julia 1.9.
3038
"""
3039
function filter(f)
1✔
3040
    Fix1(filter, f)
1✔
3041
end
3042

3043
"""
3044
    keepat!(a::Vector, inds)
3045
    keepat!(a::BitVector, inds)
3046

3047
Remove the items at all the indices which are not given by `inds`,
3048
and return the modified `a`.
3049
Items which are kept are shifted to fill the resulting gaps.
3050

3051
$(_DOCS_ALIASING_WARNING)
3052

3053
`inds` must be an iterator of sorted and unique integer indices.
3054
See also [`deleteat!`](@ref).
3055

3056
!!! compat "Julia 1.7"
3057
    This function is available as of Julia 1.7.
3058

3059
# Examples
3060
```jldoctest
3061
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
3062
3-element Vector{Int64}:
3063
 6
3064
 4
3065
 2
3066
```
3067
"""
3068
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
3069

3070
"""
3071
    keepat!(a::Vector, m::AbstractVector{Bool})
3072
    keepat!(a::BitVector, m::AbstractVector{Bool})
3073

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

3078
# Examples
3079
```jldoctest
3080
julia> a = [:a, :b, :c];
3081

3082
julia> keepat!(a, [true, false, true])
3083
2-element Vector{Symbol}:
3084
 :a
3085
 :c
3086

3087
julia> a
3088
2-element Vector{Symbol}:
3089
 :a
3090
 :c
3091
```
3092
"""
3093
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
168✔
3094

3095
# set-like operators for vectors
3096
# These are moderately efficient, preserve order, and remove dupes.
3097

3098
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
10,428✔
3099
    # P, U force specialization
3100
    if pred(x, state)
18,377✔
3101
        update!(state, x)
7,307✔
3102
        true
3103
    else
3104
        false
3105
    end
3106
end
3107

3108
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
202✔
3109
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
778✔
3110

3111
function _grow!(pred!, v::AbstractVector, itrs)
86✔
3112
    filter!(pred!, v) # uniquify v
212✔
3113
    for itr in itrs
212✔
3114
        mapfilter(pred!, push!, itr, v)
427✔
3115
    end
633✔
3116
    return v
212✔
3117
end
3118

3119
union!(v::AbstractVector{T}, itrs...) where {T} =
202✔
3120
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3121

3122
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
10✔
3123
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3124

3125
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
×
3126
    seen = Set{eltype(v)}()
×
3127
    filter!(_grow_filter!(seen), v)
×
3128
    shrinker!(seen, itrs...)
×
3129
    filter!(in(seen), v)
×
3130
end
3131

3132
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
×
3133
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
×
3134

3135
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
768✔
3136

3137
function _shrink(shrinker!::F, itr, itrs) where F
708✔
3138
    T = promote_eltype(itr, itrs...)
710✔
3139
    keep = shrinker!(Set{T}(itr), itrs...)
1,718✔
3140
    vectorfilter(T, _shrink_filter!(keep), itr)
710✔
3141
end
3142

3143
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
322✔
3144
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
388✔
3145

3146
function intersect(v::AbstractVector, r::AbstractRange)
4✔
3147
    T = promote_eltype(v, r)
58✔
3148
    common = Iterators.filter(in(r), v)
58✔
3149
    seen = Set{T}(common)
58✔
3150
    return vectorfilter(T, _shrink_filter!(seen), common)
58✔
3151
end
3152
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
2✔
3153

3154
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3155
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
4,564✔
3156
    if i isa Bool # Not via dispatch to avoid ambiguities
555,199,298✔
3157
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3158
    else
3159
        _getindex(v, i)
853,580,110✔
3160
    end
3161
end
3162

3163
"""
3164
    wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
3165

3166
Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version
3167
of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers.
3168
"""
3169
function wrap end
3170

3171
# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller
3172
function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N}
×
3173
    mem = ref.mem
99,507✔
3174
    mem_len = length(mem) + 1 - memoryrefoffset(ref)
99,507✔
3175
    len = Core.checked_dims(dims...)
99,346✔
3176
    @boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len)
99,507✔
3177
    return ref
99,340✔
3178
end
3179

3180
@noinline invalid_wrap_err(len, dims, proddims) = throw(DimensionMismatch(LazyString(
1✔
3181
    "Attempted to wrap a MemoryRef of length ", len, " with an Array of size dims=", dims,
3182
    " which is invalid because prod(dims) = ", proddims, " > ", len,
3183
    " so that the array would have more elements than the underlying memory can store.")))
3184

3185
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
4✔
3186
    dims = convert(Dims, dims)
4✔
3187
    ref = _wrap(m, dims)
4✔
3188
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
4✔
3189
end
3190

3191
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
3✔
3192
    dims = convert(Dims, dims)
3✔
3193
    ref = _wrap(memoryref(m), dims)
4✔
3194
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
2✔
3195
end
3196
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
4✔
3197
    dims = (Int(l),)
99,498✔
3198
    ref = _wrap(m, dims)
99,501✔
3199
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
99,333✔
3200
end
3201
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
1✔
3202
    dims = (Int(l),)
1✔
3203
    ref = _wrap(memoryref(m), (l,))
1✔
3204
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
1✔
3205
end
3206
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
108✔
3207
    ref = memoryref(m)
380,396✔
3208
    dims = (length(m),)
380,396✔
3209
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
363,516✔
3210
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