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

JuliaLang / julia / 1257

01 Sep 2025 06:55PM UTC coverage: 76.743% (+2.0%) from 74.77%
1257

push

buildkite

web-flow
Bump actions/checkout from 4.2.2 to 5.0.0 (#59453)

61036 of 79533 relevant lines covered (76.74%)

23153196.42 hits per line

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

92.39
/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
10,903✔
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}()
606,947✔
159
function vect(X::T...) where T
30,162✔
160
    @_terminates_locally_meta
347,188✔
161
    vec = Vector{T}(undef, length(X))
383,207✔
162
    @_safeindex for i = 1:length(X)
412,439✔
163
        vec[i] = X[i]
836,370✔
164
    end
1,276,878✔
165
    return vec
371,163✔
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...)
1,206,330✔
184
    T = promote_typeof(X...)
1,207,187✔
185
    return T[X...]
1,207,598✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
34,134✔
190
    d < 1 && error("arraysize: dimension out of range")
131,479,871✔
191
    sz = getfield(a, :size)
131,854,937✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
196,346,706✔
193
end
194

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

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

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

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

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

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

215
function _unsetindex!(A::Array, i::Int)
1,425✔
216
    @inline
452,300,591✔
217
    @boundscheck checkbounds(A, i)
471,034,803✔
218
    @inbounds _unsetindex!(memoryref(A.ref, i))
472,757,830✔
219
    return A
454,285,706✔
220
end
221

222

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

234
sizeof(a::Array) = length(a) * elsize(typeof(a)) # n.b. this ignores bitsunion bytes, as a historical fact
207,709✔
235

236
function isassigned(a::Array, i::Int...)
124,456✔
237
    @inline
1,131,152✔
238
    @_noub_if_noinbounds_meta
1,131,152✔
239
    @boundscheck checkbounds(Bool, a, i...) || return false
1,131,180✔
240
    ii = _sub2ind(size(a), i...)
1,131,124✔
241
    return @inbounds isassigned(memoryrefnew(a.ref, ii, false))
1,131,124✔
242
end
243

244
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
268✔
245
    @inline
111,923,376✔
246
    @_noub_if_noinbounds_meta
111,849,426✔
247
    @boundscheck checkbounds(Bool, a, i) || return false
112,199,052✔
248
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
112,283,940✔
249
end
250

251

252
## copy ##
253

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

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

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

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

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

277
The `unsafe` prefix on this function indicates that no validation is performed to ensure
278
that n is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
279
the same manner as C.
280
"""
281
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
11✔
282
    n == 0 && return dest
9,758,384✔
283
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
19,321,532✔
284
    return dest
9,660,768✔
285
end
286

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

290
Copy `n` elements from collection `src` starting at the linear index `soffs`, to array `dest` starting at
291
the index `doffs`. Return `dest`.
292
"""
293
copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
192,485✔
294
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
387✔
295
copyto!(dest::Memory, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
153,494,917✔
296

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

300
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
114✔
301
    n == 0 && return dest
85,142,729✔
302
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
84,346,494✔
303
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
84,349,048✔
304
    @boundscheck checkbounds(src, soffs:soffs+n-1)
84,348,948✔
305
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
84,348,971✔
306
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
307
        unsafe_copyto!(dest, src, n)
165,890,815✔
308
    end
309
    return dest
81,541,979✔
310
end
311

312

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

318
_copyto2arg!(dest, src) = copyto!(dest, firstindex(dest), src, firstindex(src), length(src))
2,687,456✔
319

320
copyto!(dest::Array, src::Array) = _copyto2arg!(dest, src)
107,659✔
321
copyto!(dest::Array, src::Memory) = _copyto2arg!(dest, src)
×
322
copyto!(dest::Memory, src::Array) = _copyto2arg!(dest, src)
×
323

324
# also to avoid ambiguities in packages
325
copyto!(dest::Array{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
2,579,371✔
326
copyto!(dest::Array{T}, src::Memory{T}) where {T} = _copyto2arg!(dest, src)
387✔
327
copyto!(dest::Memory{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
39✔
328

329
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
330
# for bootstrapping purposes.
331
function fill!(dest::Array{T}, x) where T
14,253✔
332
    @inline
22,643,312✔
333
    x = x isa T ? x : convert(T, x)::T
22,643,404✔
334
    return _fill!(dest, x)
4,931,191,104✔
335
end
336
function _fill!(dest::Array{T}, x::T) where T
11,352✔
337
    for i in eachindex(dest)
34,794,303✔
338
        dest[i] = x
4,964,734,964✔
339
    end
6,442,450,941✔
340
    return dest
23,006,429✔
341
end
342

343
"""
344
    copy(x)
345

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

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

354
@eval function copy(a::Array)
456,860✔
355
    # `copy` only throws when the size exceeds the max allocation size,
356
    # but since we're copying an existing array, we're guaranteed that this will not happen.
357
    @_nothrow_meta
6,785,426✔
358
    ref = a.ref
8,537,181✔
359
    newmem = typeof(ref.mem)(undef, length(a))
8,537,202✔
360
    @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a))
15,059,126✔
361
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
8,537,153✔
362
end
363

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

375
## Constructors ##
376

377
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
361,471✔
378
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
10,146✔
379
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
27,623✔
380
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
31,012✔
381
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
56,652✔
382
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
10,848,650✔
383
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
1,098✔
384
similar(::Type{Array{T,N}}, dims::Dims) where {T,N} = similar(Array{T}, dims)
44,242,864✔
385

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

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

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

401
julia> getindex(Int8, 1, 2, 3)
402
3-element Vector{Int8}:
403
 1
404
 2
405
 3
406
```
407
"""
408
function getindex(::Type{T}, vals...) where T
260,590✔
409
    @inline
21,605,628✔
410
    @_effect_free_terminates_locally_meta
21,605,626✔
411
    a = Vector{T}(undef, length(vals))
98,902,253✔
412
    if vals isa NTuple
21,605,639✔
413
        @_safeindex for i in 1:length(vals)
21,429,654✔
414
            a[i] = vals[i]
1,824,217✔
415
        end
1,751,458✔
416
    else
417
        # use afoldl to avoid type instability inside loop
418
        afoldl(1, vals...) do i, v
176,379✔
419
            @inbounds a[i] = v
371,463✔
420
            return i + 1
371,463✔
421
        end
422
    end
423
    return a
21,605,695✔
424
end
425

426
function getindex(::Type{Any}, @nospecialize vals...)
2,126,774✔
427
    @_effect_free_terminates_locally_meta
2,327,871✔
428
    a = Vector{Any}(undef, length(vals))
2,369,270✔
429
    @_safeindex for i = 1:length(vals)
3,689,880✔
430
        a[i] = vals[i]
6,305,956✔
431
    end
10,157,265✔
432
    return a
2,330,988✔
433
end
434
getindex(::Type{Any}) = Vector{Any}()
76,956,876✔
435

436
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
24✔
437
    ref = a.ref
456,530✔
438
    t = @_gc_preserve_begin ref
456,530✔
439
    p = unsafe_convert(Ptr{Cvoid}, ref)
456,530✔
440
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
456,536✔
441
    @_gc_preserve_end t
456,524✔
442
    return a
232,216✔
443
end
444

445
to_dim(d::Integer) = d
×
446
to_dim(d::OneTo) = last(d)
618✔
447

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

546
fill(v, dims::DimOrInd...) = fill(v, dims)
114,566,710✔
547
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
548
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
114,566,865✔
549
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
39✔
550
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
379✔
551

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

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

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

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

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

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

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

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

594
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
595
    @eval begin
596
        $fname(dims::DimOrInd...) = $fname(dims)
448,929✔
597
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
3,898,520,104✔
598
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
466,258✔
599
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
3,357✔
600
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
35,939✔
601
            a = Array{T,N}(undef, dims)
4,982,809✔
602
            fill!(a, $felt(T))
4,775,092,854✔
603
            return a
4,758,170✔
604
        end
605
        function $fname(::Type{T}, dims::Tuple{}) where {T}
606
            a = Array{T}(undef)
50✔
607
            fill!(a, $felt(T))
50✔
608
            return a
50✔
609
        end
610
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
611
            a = similar(Array{T,N}, dims)
4,926✔
612
            fill!(a, $felt(T))
11,044✔
613
            return a
4,926✔
614
        end
615
    end
616
end
617

618
## Conversions ##
619

620
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
162,981✔
621

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

624
## Constructors ##
625

626
# constructors should make copies
627
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
144,963✔
628
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
20,687✔
629

630
## copying iterators to containers
631

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

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

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

649
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
19,091✔
650
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
651
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
432,891✔
652
    a = Vector{T}()
432,910✔
653
    for x in itr
808,034✔
654
        push!(a, x)
633,807✔
655
    end
892,486✔
656
    return a
432,910✔
657
end
658

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

662
_similar_shape(itr, ::SizeUnknown) = nothing
432✔
663
_similar_shape(itr, ::HasLength) = length(itr)::Integer
2,339,304✔
664
_similar_shape(itr, ::HasShape) = axes(itr)
43,640,702✔
665

666
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,394,770✔
667
    similar(c, T, 0)
668
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
288,886✔
669
    similar(c, T, len)
670
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
528,693✔
671
    similar(c, T, axs)
672

673
# make a collection appropriate for collecting `itr::Generator`
674
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
432✔
675
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
1,978,042✔
676
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
35,028,813✔
677

678
# used by syntax lowering for simple typed comprehensions
679
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
42,623,825✔
680

681

682
"""
683
    collect(iterator)
684

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

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

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

697
# Examples
698

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

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

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

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

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

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

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

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

736
collect(A::AbstractArray) = _collect_indices(axes(A), A)
275,075✔
737

738
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
738,239✔
739

740
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
239,068✔
741
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
742

743
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,394,496✔
744
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,394,655✔
745
    for x in itr
2,785,782✔
746
        push!(a,x)
22,627,517✔
747
    end
39,019,114✔
748
    return a
1,394,339✔
749
end
750

751
function _collect_indices(::Tuple{}, A)
752
    dest = Array{eltype(A),0}(undef)
53✔
753
    isempty(A) && return dest
53✔
754
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
53✔
755
end
756
function _collect_indices(indsA::Tuple{Vararg{OneTo}}, A)
7,324✔
757
    dest = Array{eltype(A)}(undef, length.(indsA))
185,790✔
758
    isempty(A) && return dest
185,790✔
759
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
185,752✔
760
end
761
function _collect_indices(indsA, A)
74✔
762
    B = Array{eltype(A)}(undef, length.(indsA))
254✔
763
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
254✔
764
end
765

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

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

796
function collect(itr::Generator)
1,496,140✔
797
    isz = IteratorSize(itr.iter)
2,865,405✔
798
    et = @default_eltype(itr)
799
    if isa(isz, SizeUnknown)
2,865,405✔
800
        return grow_to!(Vector{et}(), itr)
304,807✔
801
    else
802
        shp = _similar_shape(itr, isz)
2,562,875✔
803
        y = iterate(itr)
4,047,755✔
804
        if y === nothing
2,560,698✔
805
            return _array_for(et, isz, shp)
1,874✔
806
        end
807
        v1, st = y
2,558,824✔
808
        dest = _array_for(typeof(v1), isz, shp)
2,559,296✔
809
        # The typeassert gives inference a helping hand on the element type and dimensionality
810
        # (work-around for #28382)
811
        et′ = et <: Type ? Type : et
2,558,827✔
812
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
2,559,283✔
813
        collect_to_with_first!(dest, v1, itr, st)::RT
32,540,824✔
814
    end
815
end
816

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

820
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
265,181✔
821
    et = @default_eltype(itr)
346,107✔
822
    shp = _similar_shape(itr, isz)
526,017✔
823
    y = iterate(itr)
1,048,149✔
824
    if y === nothing
526,003✔
825
        return _similar_for(c, et, itr, isz, shp)
3,663✔
826
    end
827
    v1, st = y
342,441✔
828
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
522,536✔
829
    # The typeassert gives inference a helping hand on the element type and dimensionality
830
    # (work-around for #28382)
831
    et′ = et <: Type ? Type : et
342,441✔
832
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
342,602✔
833
    collect_to_with_first!(dest, v1, itr, st)::RT
522,340✔
834
end
835

836
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
256,618✔
837
    i1 = first(LinearIndices(dest))
2,902,538✔
838
    dest[i1] = v1
3,081,463✔
839
    return collect_to!(dest, itr, i1+1, st)
33,951,759✔
840
end
841

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

847
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
5,340✔
848
    @inline
5,825✔
849
    new = similar(dest, promote_typejoin(T, typeof(el)))
5,831✔
850
    f = first(LinearIndices(dest))
5,825✔
851
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
11,611✔
852
    @inbounds new[i] = el
5,831✔
853
    return new
5,831✔
854
end
855

856
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
1,429,877✔
857
    # collect to dest array, checking the type of each result. if a result does not
858
    # match, widen the result type and re-dispatch.
859
    i = offs
2,908,215✔
860
    while true
260,722,734✔
861
        y = iterate(itr, st)
518,355,123✔
862
        y === nothing && break
260,722,717✔
863
        el, st = y
256,753,089✔
864
        if el isa T
256,753,089✔
865
            @inbounds dest[i] = el
257,635,588✔
866
            i += 1
257,635,588✔
867
        else
868
            new = setindex_widen_up_to(dest, el, i)
5,799✔
869
            return collect_to!(new, itr, i+1, st)
5,799✔
870
        end
871
    end
257,635,588✔
872
    return dest
3,081,331✔
873
end
874

875
function grow_to!(dest, itr)
4,487✔
876
    y = iterate(itr)
306,640✔
877
    y === nothing && return dest
304,850✔
878
    dest2 = empty(dest, typeof(y[1]))
1,876✔
879
    push!(dest2, y[1])
2,124✔
880
    grow_to!(dest2, itr, y[2])
1,857✔
881
end
882

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

896
function grow_to!(dest, itr, st)
2,001✔
897
    T = eltype(dest)
2,030✔
898
    y = iterate(itr, st)
3,460✔
899
    while y !== nothing
11,802✔
900
        el, st = y
9,927✔
901
        if el isa T
9,927✔
902
            push!(dest, el)
9,776✔
903
        else
904
            new = push_widen(dest, el)
159✔
905
            return grow_to!(new, itr, st)
155✔
906
        end
907
        y = iterate(itr, st)
12,912✔
908
    end
9,772✔
909
    return dest
1,875✔
910
end
911

912
## Indexing: getindex ##
913

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

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

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

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

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

935
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
153,844✔
936
    @inline
380,009,152✔
937
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
511,071,644✔
938
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
511,076,633✔
939
end
940

941
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
942
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
92,698✔
943
    @inline
4,366,243✔
944
    @boundscheck checkbounds(A, I)
9,808,378✔
945
    lI = length(I)
9,808,371✔
946
    X = similar(A, axes(I))
9,808,392✔
947
    if lI > 0
9,808,369✔
948
        copyto!(X, firstindex(X), A, first(I), lI)
11,472,330✔
949
    end
950
    return X
9,795,204✔
951
end
952

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

956
function getindex(A::Array, c::Colon)
8,915✔
957
    lI = length(A)
49,065✔
958
    X = similar(A, lI)
49,065✔
959
    if lI > 0
49,065✔
960
        unsafe_copyto!(X, 1, A, 1, lI)
98,118✔
961
    end
962
    return X
49,065✔
963
end
964

965
# This is redundant with the abstract fallbacks, but needed for bootstrap
966
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
9,508,291✔
967
    return S[ A[i] for i in I ]
9,508,851✔
968
end
969

970
## Indexing: setindex! ##
971

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

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

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

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

992
function setindex!(A::Array{T}, x, i::Int) where {T}
9,967,367✔
993
    @_propagate_inbounds_meta
6,222,753,438✔
994
    x = x isa T ? x : convert(T, x)::T
6,227,099,475✔
995
    return _setindex!(A, x, i)
6,442,450,941✔
996
end
997
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
13,893✔
998
    @_noub_if_noinbounds_meta
6,219,806,864✔
999
    @boundscheck checkbounds(Bool, A, i) || throw_boundserror(A, (i,))
6,442,450,941✔
1000
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
6,442,450,941✔
1001
    return A
6,442,450,941✔
1002
end
1003
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
2,536,459✔
1004
    @_propagate_inbounds_meta
160,124,354✔
1005
    x = x isa T ? x : convert(T, x)::T
160,135,367✔
1006
    return _setindex!(A, x, i1, i2, I...)
206,189,125✔
1007
end
1008
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
8✔
1009
    @inline
156,997,272✔
1010
    @_noub_if_noinbounds_meta
156,997,307✔
1011
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
206,201,142✔
1012
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
206,202,517✔
1013
    return A
203,312,529✔
1014
end
1015

1016
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
240,786,839✔
1017
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
247,263,312✔
1018
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
75,415,683✔
1019
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
208,591,306✔
1020
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
1021
    __safe_setindex!(A, convert(T, x)::T, i))
88,745✔
1022

1023
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1024
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
367✔
1025
    @_propagate_inbounds_meta
2,478,023✔
1026
    @boundscheck setindex_shape_check(X, length(I))
2,530,814✔
1027
    @boundscheck checkbounds(A, I)
2,530,814✔
1028
    require_one_based_indexing(X)
2,478,023✔
1029
    X′ = unalias(A, X)
2,479,488✔
1030
    I′ = unalias(A, I)
2,478,025✔
1031
    count = 1
2,478,023✔
1032
    for i in I′
2,618,685✔
1033
        @inbounds A[i] = X′[count]
17,816,391✔
1034
        count += 1
17,816,391✔
1035
    end
33,243,194✔
1036
    return A
2,518,895✔
1037
end
1038

1039
# Faster contiguous setindex! with copyto!
1040
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
335✔
1041
    @inline
3,039,085✔
1042
    @boundscheck checkbounds(A, I)
3,039,307✔
1043
    lI = length(I)
3,039,307✔
1044
    @boundscheck setindex_shape_check(X, lI)
3,039,307✔
1045
    if lI > 0
3,039,307✔
1046
        unsafe_copyto!(A, first(I), X, 1, lI)
6,076,882✔
1047
    end
1048
    return A
3,039,239✔
1049
end
1050
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
89✔
1051
    @inline
149✔
1052
    lI = length(A)
149✔
1053
    @boundscheck setindex_shape_check(X, lI)
149✔
1054
    if lI > 0
149✔
1055
        unsafe_copyto!(A, 1, X, 1, lI)
298✔
1056
    end
1057
    return A
149✔
1058
end
1059

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

1076
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
32,743,307✔
1077

1078
function _growbeg_internal!(a::Vector, delta::Int, len::Int)
624,119✔
1079
    @_terminates_locally_meta
624,119✔
1080
    ref = a.ref
624,118✔
1081
    mem = ref.mem
624,103✔
1082
    offset = memoryrefoffset(ref)
624,112✔
1083
    newlen = len + delta
624,106✔
1084
    memlen = length(mem)
624,105✔
1085
    if offset + len - 1 > memlen || offset < 1
1,248,112✔
1086
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1087
    end
1088
    # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1089
    # the +1 is because I didn't want to have an off by 1 error.
1090
    newmemlen = max(overallocation(len), len + 2 * delta + 1)
935,159✔
1091
    newoffset = div(newmemlen - newlen, 2) + 1
624,002✔
1092
    # If there is extra data after the end of the array we can use that space so long as there is enough
1093
    # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1094
    # Specifically, we want to ensure that we will only do this operation once before
1095
    # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1096
    if newoffset + newlen < memlen
624,055✔
1097
        newoffset = div(memlen - newlen, 2) + 1
6,272✔
1098
        newmem = mem
6,272✔
1099
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
9,059✔
1100
        for j in offset:newoffset+delta-1
6,900✔
1101
            @inbounds _unsetindex!(mem, j)
117,981✔
1102
        end
198,866✔
1103
    else
1104
        newmem = array_new_memory(mem, newmemlen)
617,796✔
1105
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
617,851✔
1106
    end
1107
    if ref !== a.ref
624,120✔
1108
        throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1109
    end
1110
    setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
624,117✔
1111
end
1112

1113
function _growbeg!(a::Vector, delta::Integer)
73✔
1114
    @_noub_meta
19,086,524✔
1115
    delta = Int(delta)
19,086,524✔
1116
    delta == 0 && return # avoid attempting to index off the end
19,112,952✔
1117
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
19,112,026✔
1118
    ref = a.ref
19,938,977✔
1119
    mem = ref.mem
19,086,361✔
1120
    len = length(a)
19,938,983✔
1121
    offset = memoryrefoffset(ref)
19,938,985✔
1122
    newlen = len + delta
19,938,981✔
1123
    setfield!(a, :size, (newlen,))
19,938,978✔
1124
    # if offset is far enough advanced to fit data in existing memory without copying
1125
    if delta <= offset - 1
19,938,978✔
1126
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
19,288,947✔
1127
    else
1128
        @noinline _growbeg_internal!(a, delta, len)
650,066✔
1129
    end
1130
    return
19,939,081✔
1131
end
1132

1133
function _growend_internal!(a::Vector, delta::Int, len::Int)
29,938,506✔
1134
    ref = a.ref
29,938,519✔
1135
    mem = ref.mem
29,938,404✔
1136
    memlen = length(mem)
29,938,931✔
1137
    newlen = len + delta
29,938,909✔
1138
    offset = memoryrefoffset(ref)
29,938,821✔
1139
    newmemlen = offset + newlen - 1
29,938,826✔
1140
    if offset + len - 1 > memlen || offset < 1
59,877,108✔
1141
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1142
    end
1143

1144
    if offset - 1 > div(5 * newlen, 4)
29,938,645✔
1145
        # If the offset is far enough that we can copy without resizing
1146
        # while maintaining proportional spacing on both ends of the array
1147
        # note that this branch prevents infinite growth when doing combinations
1148
        # of push! and popfirst! (i.e. when using a Vector as a queue)
1149
        newmem = mem
1,083✔
1150
        newoffset = div(newlen, 8) + 1
1,083✔
1151
    else
1152
        # grow either by our computed overallocation factor
1153
        # or exactly the requested size, whichever is larger
1154
        # TODO we should possibly increase the offset if the current offset is nonzero.
1155
        newmemlen2 = max(overallocation(memlen), newmemlen)
31,287,838✔
1156
        newmem = array_new_memory(mem, newmemlen2)
29,941,678✔
1157
        newoffset = offset
29,937,513✔
1158
    end
1159
    newref = @inbounds memoryref(newmem, newoffset)
29,938,623✔
1160
    unsafe_copyto!(newref, ref, len)
31,858,721✔
1161
    if ref !== a.ref
29,938,498✔
1162
        @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1163
    end
1164
    setfield!(a, :ref, newref)
29,938,368✔
1165
return
29,938,375✔
1166
end
1167

1168
function _growend!(a::Vector, delta::Integer)
1,352✔
1169
    @_noub_meta
328,165,716✔
1170
    delta = Int(delta)
328,165,723✔
1171
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
328,587,980✔
1172
    ref = a.ref
446,951,936✔
1173
    mem = ref.mem
446,950,235✔
1174
    memlen = length(mem)
446,967,940✔
1175
    len = length(a)
446,966,646✔
1176
    newlen = len + delta
446,959,780✔
1177
    offset = memoryrefoffset(ref)
446,956,872✔
1178
    setfield!(a, :size, (newlen,))
446,956,905✔
1179
    newmemlen = offset + newlen - 1
446,956,903✔
1180
    if memlen < newmemlen
446,965,918✔
1181
        @noinline _growend_internal!(a, delta, len)
34,701,700✔
1182
    end
1183
    return
446,808,275✔
1184
end
1185

1186
function _growat!(a::Vector, i::Integer, delta::Integer)
1,936,139✔
1187
    @_terminates_globally_noub_meta
1,936,143✔
1188
    delta = Int(delta)
1,936,144✔
1189
    i = Int(i)
1,936,125✔
1190
    i == 1 && return _growbeg!(a, delta)
1,936,132✔
1191
    len = length(a)
1,305,786✔
1192
    i == len + 1 && return _growend!(a, delta)
1,305,806✔
1193
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,133,134✔
1194
    1 < i <= len || throw(BoundsError(a, i))
1,133,132✔
1195
    ref = a.ref
1,133,118✔
1196
    mem = ref.mem
1,133,103✔
1197
    memlen = length(mem)
1,133,110✔
1198
    newlen = len + delta
1,133,105✔
1199
    offset = memoryrefoffset(ref)
1,133,101✔
1200
    setfield!(a, :size, (newlen,))
1,133,115✔
1201
    newmemlen = offset + newlen - 1
1,133,112✔
1202

1203
    # which side would we rather grow into?
1204
    prefer_start = i <= div(len, 2)
1,133,123✔
1205
    # if offset is far enough advanced to fit data in beginning of the memory
1206
    if prefer_start && delta <= offset - 1
1,133,112✔
1207
        newref = @inbounds memoryref(mem, offset - delta)
361,590✔
1208
        unsafe_copyto!(newref, ref, i)
723,180✔
1209
        setfield!(a, :ref, newref)
361,590✔
1210
        for j in i:i+delta-1
547,102✔
1211
            @inbounds _unsetindex!(a, j)
450,103✔
1212
        end
436,126✔
1213
    elseif !prefer_start && memlen >= newmemlen
771,514✔
1214
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
1,131,036✔
1215
        for j in i:i+delta-1
755,967✔
1216
            @inbounds _unsetindex!(a, j)
659,215✔
1217
        end
640,927✔
1218
    else
1219
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1220
        # the +1 is because I didn't want to have an off by 1 error.
1221
        newmemlen = max(overallocation(memlen), len+2*delta+1)
339,991✔
1222
        newoffset = (newmemlen - newlen) ÷ 2 + 1
205,941✔
1223
        newmem = array_new_memory(mem, newmemlen)
205,954✔
1224
        newref = @inbounds memoryref(newmem, newoffset)
205,984✔
1225
        unsafe_copyto!(newref, ref, i-1)
411,917✔
1226
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
411,894✔
1227
        setfield!(a, :ref, newref)
205,945✔
1228
    end
1229
end
1230

1231
# efficiently delete part of an array
1232
function _deletebeg!(a::Vector, delta::Integer)
264,999✔
1233
    delta = Int(delta)
23,577,103✔
1234
    len = length(a)
26,448,928✔
1235
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
26,448,929✔
1236
    for i in 1:delta
23,830,693✔
1237
        @inbounds _unsetindex!(a, i)
49,253,822✔
1238
    end
68,204,912✔
1239
    newlen = len - delta
26,448,927✔
1240
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
26,448,926✔
1241
        newref = @inbounds memoryref(a.ref, delta + 1)
26,100,107✔
1242
        setfield!(a, :ref, newref)
26,100,109✔
1243
    end
1244
    setfield!(a, :size, (newlen,))
26,448,928✔
1245
    return
26,448,926✔
1246
end
1247
function _deleteend!(a::Vector, delta::Integer)
322✔
1248
    delta = Int(delta)
16,191,265✔
1249
    len = length(a)
30,784,174✔
1250
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
30,784,177✔
1251
    newlen = len - delta
30,784,202✔
1252
    for i in newlen+1:len
45,872,321✔
1253
        @inbounds _unsetindex!(a, i)
401,890,835✔
1254
    end
771,710,499✔
1255
    setfield!(a, :size, (newlen,))
30,784,172✔
1256
    return
30,784,152✔
1257
end
1258
function _deleteat!(a::Vector, i::Integer, delta::Integer)
497,561✔
1259
    i = Int(i)
497,561✔
1260
    len = length(a)
497,562✔
1261
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
497,565✔
1262
    1 <= i <= len || throw(BoundsError(a, i))
497,566✔
1263
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
497,571✔
1264
    newa = a
497,570✔
1265
    if 2*i + delta <= len
497,570✔
1266
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
327,817✔
1267
        _deletebeg!(a, delta)
22,418,976✔
1268
    else
1269
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
570,347✔
1270
        _deleteend!(a, delta)
328,804✔
1271
    end
1272
    return
497,557✔
1273
end
1274
## Dequeue functionality ##
1275

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

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

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

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

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

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

1304
function push!(a::Vector{T}, item) where T
83,137✔
1305
    @inline
70,914,066✔
1306
    # convert first so we don't grow the array if the assignment won't work
1307
    # and also to avoid a dynamic dynamic dispatch in the common case that
1308
    # `item` is poorly-typed and `a` is well-typed
1309
    item = item isa T ? item : convert(T, item)::T
70,979,432✔
1310
    return _push!(a, item)
187,829,870✔
1311
end
1312
function _push!(a::Vector{T}, item::T) where T
1,209✔
1313
    _growend!(a, 1)
187,828,637✔
1314
    @_safeindex a[length(a)] = item
187,833,366✔
1315
    return a
187,765,860✔
1316
end
1317

1318
# specialize and optimize the single argument case
1319
function push!(a::Vector{Any}, @nospecialize x)
1,906✔
1320
    _growend!(a, 1)
239,781,564✔
1321
    @_safeindex a[length(a)] = x
239,781,549✔
1322
    return a
239,781,534✔
1323
end
1324
function push!(a::Vector{Any}, @nospecialize x...)
50✔
1325
    @_terminates_locally_meta
116✔
1326
    na = length(a)
116✔
1327
    nx = length(x)
116✔
1328
    _growend!(a, nx)
116✔
1329
    @_safeindex for i = 1:nx
116✔
1330
        a[na+i] = x[i]
402✔
1331
    end
688✔
1332
    return a
116✔
1333
end
1334

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

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

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

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

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

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

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

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

1373
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
30,597✔
1374
    items isa Tuple && (items = map(x -> convert(T, x), items))
7,571,669✔
1375
    n = Int(length(items))::Int
3,230,175✔
1376
    _growend!(a, n)
3,236,475✔
1377
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
3,457,402✔
1378
    return a
3,236,469✔
1379
end
1380

1381
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
577,961✔
1382
push!(a::AbstractVector, iter...) = append!(a, iter)
2,226,323✔
1383
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
38✔
1384

1385
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
358,569✔
1386
    n = Int(length(iter))::Int
360,970✔
1387
    i = lastindex(a)
358,597✔
1388
    sizehint!(a, length(a) + n; shrink=false)
358,597✔
1389
    for item in iter
447,998✔
1390
        push!(a, item)
174,190✔
1391
    end
205,646✔
1392
    a
358,563✔
1393
end
1394
function _append!(a::AbstractVector, ::IteratorSize, iter)
219,331✔
1395
    for item in iter
305,039✔
1396
        push!(a, item)
139,086✔
1397
    end
140,640✔
1398
    a
219,335✔
1399
end
1400

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

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

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

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

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

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

1432
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
6,453✔
1433
    items isa Tuple && (items = map(x -> convert(T, x), items))
3,830✔
1434
    n = length(items)
10,062✔
1435
    _growbeg!(a, n)
19,204✔
1436
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1437
    # just the last n elements instead of all of them from the first
1438
    copyto!(a, 1, items, lastindex(items)-n+1, n)
19,192✔
1439
    return a
10,062✔
1440
end
1441

1442
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
462✔
1443
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
32✔
1444
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
14✔
1445

1446
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
422✔
1447
    @_terminates_locally_meta
424✔
1448
    require_one_based_indexing(a)
424✔
1449
    n = Int(length(iter))::Int
424✔
1450
    sizehint!(a, length(a) + n; first=true, shrink=false)
424✔
1451
    n = 0
424✔
1452
    for item in iter
426✔
1453
        n += 1
746✔
1454
        pushfirst!(a, item)
748✔
1455
    end
738✔
1456
    reverse!(a, 1, n)
412✔
1457
    a
412✔
1458
end
1459
function _prepend!(a::Vector, ::IteratorSize, iter)
6✔
1460
    n = 0
6✔
1461
    for item in iter
10✔
1462
        n += 1
16✔
1463
        pushfirst!(a, item)
22✔
1464
    end
26✔
1465
    reverse!(a, 1, n)
4✔
1466
    a
4✔
1467
end
1468

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

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

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

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

1486
julia> length(a)
1487
8
1488

1489
julia> a[1:6]
1490
6-element Vector{Int64}:
1491
 6
1492
 5
1493
 4
1494
 3
1495
 2
1496
 1
1497
```
1498
"""
1499
function resize!(a::Vector, nl_::Integer)
2,131,973✔
1500
    nl = Int(nl_)::Int
33,456,418✔
1501
    l = length(a)
33,462,405✔
1502
    if nl > l
33,462,415✔
1503
        _growend!(a, nl-l)
13,084,730✔
1504
    elseif nl != l
20,377,815✔
1505
        if nl < 0
5,367,572✔
1506
            _throw_argerror("new length must be ≥ 0")
×
1507
        end
1508
        _deleteend!(a, l-nl)
5,367,574✔
1509
    end
1510
    return a
33,462,369✔
1511
end
1512

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

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

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

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

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

1531
# Notes on the performance model
1532

1533
For types that support `sizehint!`,
1534

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

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

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

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

1549
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
4,974,697✔
1550
    len = length(a)
2,466,449✔
1551
    ref = a.ref
2,466,450✔
1552
    mem = ref.mem
2,466,450✔
1553
    memlen = length(mem)
2,466,450✔
1554
    sz = max(Int(sz), len)
2,466,450✔
1555
    inc = sz - len
2,466,450✔
1556
    if sz <= memlen
2,466,450✔
1557
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1558
        if !shrink || memlen - sz <= div(memlen, 8)
4,326,009✔
1559
            return a
342,701✔
1560
        end
1561
        newmem = array_new_memory(mem, sz)
1,995,546✔
1562
        if first
1,991,083✔
1563
            newref = memoryref(newmem, inc + 1)
×
1564
        else
1565
            newref = memoryref(newmem)
1,991,083✔
1566
        end
1567
        unsafe_copyto!(newref, ref, len)
1,998,354✔
1568
        setfield!(a, :ref, newref)
1,991,083✔
1569
    elseif first
132,666✔
1570
        _growbeg!(a, inc)
×
1571
        newref = getfield(a, :ref)
×
1572
        newref = memoryref(newref, inc + 1)
×
1573
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
×
1574
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
×
1575
    else # last
1576
        _growend!(a, inc)
132,666✔
1577
        setfield!(a, :size, (len,)) # undo the size change from _growend!
132,666✔
1578
    end
1579
    a
2,123,749✔
1580
end
1581

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

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

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

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

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

1608
julia> pop!(A)
1609
3
1610

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

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

1621
julia> pop!(S)
1622
2
1623

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

1628
julia> pop!(Dict(1=>2))
1629
1 => 2
1630
```
1631
"""
1632
function pop!(a::Vector)
419,750✔
1633
    if isempty(a)
23,330,829✔
1634
        _throw_argerror("array must be non-empty")
×
1635
    end
1636
    item = a[end]
23,330,828✔
1637
    _deleteend!(a, 1)
23,330,819✔
1638
    return item
23,330,802✔
1639
end
1640

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

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

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

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

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

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

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

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

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

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

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

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

1697
# Examples
1698
```jldoctest
1699
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1700
6-element Vector{Int64}:
1701
 5
1702
 6
1703
 1
1704
 2
1705
 3
1706
 4
1707
```
1708
"""
1709
function pushfirst!(a::Vector{T}, item) where T
987✔
1710
    @inline
18,082,102✔
1711
    item = item isa T ? item : convert(T, item)::T
18,082,108✔
1712
    return _pushfirst!(a, item)
18,108,209✔
1713
end
1714
function _pushfirst!(a::Vector{T}, item::T) where T
1715
    _growbeg!(a, 1)
18,108,756✔
1716
    @_safeindex a[1] = item
18,097,771✔
1717
    return a
18,097,771✔
1718
end
1719

1720
# specialize and optimize the single argument case
1721
function pushfirst!(a::Vector{Any}, @nospecialize x)
312✔
1722
    _growbeg!(a, 1)
1,219,836✔
1723
    @_safeindex a[1] = x
1,198,930✔
1724
    return a
1,198,930✔
1725
end
1726
function pushfirst!(a::Vector{Any}, @nospecialize x...)
5✔
1727
    @_terminates_locally_meta
5✔
1728
    na = length(a)
5✔
1729
    nx = length(x)
5✔
1730
    _growbeg!(a, nx)
10✔
1731
    @_safeindex for i = 1:nx
5✔
1732
        a[i] = x[i]
15✔
1733
    end
25✔
1734
    return a
5✔
1735
end
1736

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

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

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

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

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

1757
julia> popfirst!(A)
1758
1
1759

1760
julia> A
1761
5-element Vector{Int64}:
1762
 2
1763
 3
1764
 4
1765
 5
1766
 6
1767
```
1768
"""
1769
function popfirst!(a::Vector)
1,775✔
1770
    if isempty(a)
26,330,266✔
1771
        _throw_argerror("array must be non-empty")
×
1772
    end
1773
    item = a[1]
26,330,264✔
1774
    _deletebeg!(a, 1)
26,330,258✔
1775
    return item
26,330,253✔
1776
end
1777

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

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

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

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

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

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

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

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

1838
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
102,256✔
1839
    if eltype(r) === Bool
325,196✔
1840
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
18✔
1841
    else
1842
        n = length(a)
325,176✔
1843
        f = first(r)
325,194✔
1844
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
325,174✔
1845
        isempty(r) || _deleteat!(a, f, length(r))
640,095✔
1846
        return a
325,577✔
1847
    end
1848
end
1849

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

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

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

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

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

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

1882
struct Nowhere; end
213✔
1883
push!(::Nowhere, _) = nothing
4,479,528✔
1884
_growend!(::Nowhere, _) = nothing
×
1885

1886
function _push_deleted!(dltd, a::Vector, ind)
1887
    @_propagate_inbounds_meta
4,479,532✔
1888
    if isassigned(a, ind)
4,479,532✔
1889
        push!(dltd, a[ind])
4,479,573✔
1890
    else
1891
        _growend!(dltd, 1)
×
1892
    end
1893
end
1894

1895
function _copy_item!(a::Vector, p, q)
1896
    @_propagate_inbounds_meta
13,127,652✔
1897
    if isassigned(a, q)
13,127,652✔
1898
        a[p] = a[q]
13,127,652✔
1899
    else
1900
        _unsetindex!(a, p)
×
1901
    end
1902
end
1903

1904
function _deleteat!(a::Vector, inds, dltd=Nowhere())
107,325✔
1905
    n = length(a)
215,824✔
1906
    y = iterate(inds)
107,345✔
1907
    y === nothing && return a
107,325✔
1908
    (p, s) = y
106,383✔
1909
    checkbounds(a, p)
106,391✔
1910
    @inbounds _push_deleted!(dltd, a, p)
106,387✔
1911
    q = p+1
106,375✔
1912
    while true
4,479,532✔
1913
        y = iterate(inds, s)
4,479,554✔
1914
        y === nothing && break
4,479,532✔
1915
        (i,s) = y
4,373,161✔
1916
        if !(q <= i <= n)
4,373,161✔
1917
            if i < q
4✔
1918
                _throw_argerror("indices must be unique and sorted")
2✔
1919
            else
1920
                throw(BoundsError())
2✔
1921
            end
1922
        end
1923
        while q < i
8,635,640✔
1924
            @inbounds _copy_item!(a, p, q)
4,262,483✔
1925
            p += 1; q += 1
4,262,483✔
1926
        end
4,262,483✔
1927
        @inbounds _push_deleted!(dltd, a, i)
4,373,186✔
1928
        q = i+1
4,373,157✔
1929
    end
4,373,157✔
1930
    while q <= n
8,845,148✔
1931
        @inbounds _copy_item!(a, p, q)
8,738,777✔
1932
        p += 1; q += 1
8,738,777✔
1933
    end
8,738,777✔
1934
    _deleteend!(a, n-p+1)
4,479,528✔
1935
    return a
106,371✔
1936
end
1937

1938
# Simpler and more efficient version for logical indexing
1939
function deleteat!(a::Vector, inds::AbstractVector{Bool})
12,064✔
1940
    n = length(a)
12,064✔
1941
    length(inds) == n || throw(BoundsError(a, inds))
12,076✔
1942
    p = 1
12,052✔
1943
    for (q, i) in enumerate(inds)
24,102✔
1944
        @inbounds _copy_item!(a, p, q)
126,392✔
1945
        p += !i
126,392✔
1946
    end
240,734✔
1947
    _deleteend!(a, n-p+1)
64,028✔
1948
    return a
12,052✔
1949
end
1950

1951
const _default_splice = []
1952

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

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

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

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

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

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

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

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

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

2001
To insert `replacement` before an index `n` without removing any items, use
2002
`splice!(collection, n:n-1, replacement)`.
2003
"""
2004
function splice!(a::Vector, i::Integer, ins=_default_splice)
11,056✔
2005
    v = a[i]
11,104✔
2006
    m = length(ins)
10,228✔
2007
    if m == 0
10,228✔
2008
        _deleteat!(a, i, 1)
1,618✔
2009
    elseif m == 1
8,610✔
2010
        a[i] = only(ins)
793✔
2011
    else
2012
        _growat!(a, i, m-1)
7,817✔
2013
        k = 1
7,817✔
2014
        for x in ins
7,817✔
2015
            a[i+k-1] = x
997,631✔
2016
            k += 1
997,631✔
2017
        end
997,631✔
2018
    end
2019
    return v
10,228✔
2020
end
2021

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

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

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

2034
$(_DOCS_ALIASING_WARNING)
2035

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

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

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

2047
julia> A
2048
8-element Vector{Int64}:
2049
 -1
2050
 -2
2051
 -3
2052
  2
2053
  5
2054
  4
2055
  3
2056
 -1
2057
```
2058
"""
2059
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
520,620✔
2060
    v = a[r]
731,270✔
2061
    m = length(ins)
418,806✔
2062
    if m == 0
418,806✔
2063
        deleteat!(a, r)
222,153✔
2064
        return v
111,256✔
2065
    end
2066

2067
    n = length(a)
307,550✔
2068
    f = first(r)
307,550✔
2069
    l = last(r)
307,550✔
2070
    d = length(r)
307,550✔
2071

2072
    if m < d
307,550✔
2073
        delta = d - m
37,908✔
2074
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
57,126✔
2075
    elseif m > d
269,642✔
2076
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
269,316✔
2077
    end
2078

2079
    k = 1
307,550✔
2080
    for x in ins
342,068✔
2081
        a[f+k-1] = x
12,695,588✔
2082
        k += 1
12,695,588✔
2083
    end
16,927,376✔
2084
    return v
307,550✔
2085
end
2086

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

2089
function empty!(a::Vector)
375✔
2090
    _deleteend!(a, length(a))
2,088,199✔
2091
    return a
1,808,136✔
2092
end
2093

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

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

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

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

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

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

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

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

2178
julia> reverse(A, 3, 5)
2179
5-element Vector{Int64}:
2180
 1
2181
 2
2182
 5
2183
 4
2184
 3
2185
```
2186
"""
2187
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
6,056✔
2188
    s, n = Int(start), Int(stop)
6,056✔
2189
    B = similar(A)
6,056✔
2190
    for i = firstindex(A):s-1
6,059✔
2191
        B[i] = A[i]
3,354✔
2192
    end
6,132✔
2193
    for i = s:n
9,158✔
2194
        B[i] = A[n+s-i]
512,092✔
2195
    end
1,018,142✔
2196
    for i = n+1:lastindex(A)
8,444✔
2197
        B[i] = A[i]
3,360✔
2198
    end
6,144✔
2199
    return B
6,056✔
2200
end
2201

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

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

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

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

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

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

2240
julia> reverse!(A);
2241

2242
julia> A
2243
5-element Vector{Int64}:
2244
 5
2245
 4
2246
 3
2247
 2
2248
 1
2249
```
2250
"""
2251
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
896,006✔
2252
    s, n = Int(start), Int(stop)
4,443,347✔
2253
    if n > s # non-empty and non-trivial
895,998✔
2254
        liv = LinearIndices(v)
261,610✔
2255
        if !(first(liv) ≤ s ≤ last(liv))
261,610✔
2256
            throw(BoundsError(v, s))
6✔
2257
        elseif !(first(liv) ≤ n ≤ last(liv))
261,604✔
2258
            throw(BoundsError(v, n))
×
2259
        end
2260
        r = n
261,604✔
2261
        @inbounds for i in s:midpoint(s, n-1)
481,579✔
2262
            v[i], v[r] = v[r], v[i]
23,483,070✔
2263
            r -= 1
23,483,070✔
2264
        end
46,704,536✔
2265
    end
2266
    return v
895,992✔
2267
end
2268

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

2271
vcat() = Vector{Any}()
30,355✔
2272
hcat() = Vector{Any}()
2✔
2273

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

2285
function vcat(arrays::Vector{T}...) where T
86,325✔
2286
    n = 0
86,325✔
2287
    for a in arrays
86,325✔
2288
        n += length(a)
6,173,148✔
2289
    end
6,259,365✔
2290
    arr = Vector{T}(undef, n)
86,325✔
2291
    nd = 1
86,325✔
2292
    for a in arrays
86,325✔
2293
        na = length(a)
6,173,148✔
2294
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
6,173,148✔
2295
        unsafe_copyto!(arr, nd, a, 1, na)
12,345,663✔
2296
        nd += na
6,173,148✔
2297
    end
6,259,365✔
2298
    return arr
86,325✔
2299
end
2300
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
84✔
2301

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

2304
## find ##
2305

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

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

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

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

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

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

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

2334
julia> findnext(A, CartesianIndex(1, 1))
2335
CartesianIndex(2, 1)
2336
```
2337
"""
2338
findnext(A, start) = findnext(identity, A, start)
232,178✔
2339

2340
"""
2341
    findfirst(A)
2342

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

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

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

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

2361
julia> findfirst(A)
2362
3
2363

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

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

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

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

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

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

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

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

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

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

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

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

2405
julia> findnext(isspace, "a b c", 3)
2406
4
2407
```
2408
"""
2409
function findnext(testf::Function, A, start)
30,135✔
2410
    i = oftype(first(keys(A)), start)
603,347✔
2411
    l = last(keys(A))
785,905✔
2412
    i > l && return nothing
785,905✔
2413
    while true
2,177,906✔
2414
        testf(A[i]) && return i
2,197,137✔
2415
        i == l && break
1,991,831✔
2416
        # nextind(A, l) can throw/overflow
2417
        i = nextind(A, i)
1,894,310✔
2418
    end
1,894,254✔
2419
    return nothing
97,507✔
2420
end
2421

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

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

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

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

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

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

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

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

2453
julia> findfirst(iseven, A)
2454
CartesianIndex(2, 1)
2455
```
2456
"""
2457
function findfirst(testf::Function, A)
43✔
2458
    for (i, a) in pairs(A)
62✔
2459
        testf(a) && return i
40✔
2460
    end
32✔
2461
    return nothing
23✔
2462
end
2463

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

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

2471
findfirst(::typeof(iszero), ::OneTo) = nothing
6✔
2472
findfirst(::typeof(isone), r::OneTo) = isempty(r) ? nothing : oneunit(keytype(r))
15✔
2473

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

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

2488
findfirst(::typeof(iszero), r::AbstractRange) = findfirst(==(zero(first(r))), r)
390✔
2489
findfirst(::typeof(isone), r::AbstractRange) = findfirst(==(one(first(r))), r)
9✔
2490

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

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

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

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

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

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

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

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

2521
julia> findprev(A, CartesianIndex(2, 1))
2522
CartesianIndex(2, 1)
2523
```
2524
"""
2525
findprev(A, start) = findprev(identity, A, start)
30,188✔
2526

2527
"""
2528
    findlast(A)
2529

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

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

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

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

2547
julia> findlast(A)
2548
3
2549

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

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

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

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

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

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

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

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

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

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

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

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

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

2601
julia> findprev(isspace, "a b c", 3)
2602
2
2603
```
2604
"""
2605
function findprev(testf::Function, A, start)
705✔
2606
    f = first(keys(A))
27,930✔
2607
    i = oftype(f, start)
27,959✔
2608
    i < f && return nothing
27,930✔
2609
    while true
455,087✔
2610
        testf(A[i]) && return i
455,391✔
2611
        i == f && break
427,623✔
2612
        # prevind(A, f) can throw/underflow
2613
        i = prevind(A, i)
427,239✔
2614
    end
427,157✔
2615
    return nothing
376✔
2616
end
2617

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2732
"""
2733
    findall(A)
2734

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

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

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

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

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

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

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

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

2776
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2777
function findall(A::AbstractArray{Bool})
103✔
2778
    n = count(A)
10,900✔
2779
    I = Vector{eltype(keys(A))}(undef, n)
10,885✔
2780
    cnt = 1
10,885✔
2781
    for (i,a) in pairs(A)
21,747✔
2782
        if a
611,364✔
2783
            I[cnt] = i
373,635✔
2784
            cnt += 1
373,635✔
2785
        end
2786
    end
1,211,857✔
2787
    I
10,885✔
2788
end
2789

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

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

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

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

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

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

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

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

2837
function _findin(a::Union{AbstractArray, Tuple}, b::AbstractSet)
752✔
2838
    ind  = Vector{eltype(keys(a))}()
1,124✔
2839
    @inbounds for (i,ai) in pairs(a)
1,216✔
2840
        ai in b && push!(ind, i)
181,130✔
2841
    end
361,136✔
2842
    ind
752✔
2843
end
2844
_findin(a::Union{AbstractArray, Tuple}, b) = _findin(a, Set(b))
752✔
2845

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

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

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

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

2926
## Filter ##
2927

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

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

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

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

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

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

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

2968
    j = 1
173✔
2969
    idxs = Vector{Int}(undef, length(a))
182✔
2970
    for idx in eachindex(a)
182✔
2971
        @inbounds idxs[j] = idx
229,696✔
2972
        ai = @inbounds a[idx]
229,696✔
2973
        j = ifelse(f(ai)::Bool, j+1, j)
234,295✔
2974
    end
459,221✔
2975
    resize!(idxs, j-1)
170✔
2976
    res = a[idxs]
170✔
2977
    empty!(idxs)
7,517✔
2978
    sizehint!(idxs, 0)
170✔
2979
    return res
170✔
2980
end
2981

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

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

2988
# Examples
2989
```jldoctest
2990
julia> filter!(isodd, Vector(1:10))
2991
5-element Vector{Int64}:
2992
 1
2993
 3
2994
 5
2995
 7
2996
 9
2997
```
2998
"""
2999
function filter!(f, a::AbstractVector)
3,194,543✔
3000
    j = firstindex(a)
3,195,418✔
3001
    for ai in a
3,195,417✔
3002
        @inbounds a[j] = ai
11,189,803✔
3003
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
11,750,852✔
3004
    end
11,191,368✔
3005
    j > lastindex(a) && return a
3,195,425✔
3006
    if a isa Vector
1,986,266✔
3007
        resize!(a, j-1)
1,986,264✔
3008
        sizehint!(a, j-1)
1,986,264✔
3009
    else
3010
        deleteat!(a, j:lastindex(a))
2✔
3011
    end
3012
    return a
1,986,267✔
3013
end
3014

3015
"""
3016
    filter(f)
3017

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

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

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

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

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

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

3050
$(_DOCS_ALIASING_WARNING)
3051

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

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

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

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

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

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

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

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

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

3097
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
38,706✔
3098
    # P, U force specialization
3099
    if pred(x, state)
69,543✔
3100
        update!(state, x)
20,392✔
3101
        true
3102
    else
3103
        false
3104
    end
3105
end
3106

3107
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
389✔
3108
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
2,712✔
3109

3110
function _grow!(pred!, v::AbstractVector, itrs)
185✔
3111
    filter!(pred!, v) # uniquify v
409✔
3112
    for itr in itrs
409✔
3113
        mapfilter(pred!, push!, itr, v)
832✔
3114
    end
1,229✔
3115
    return v
409✔
3116
end
3117

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

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

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

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

3134
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
2,692✔
3135

3136
function intersect(itr, itrs...)
1,028✔
3137
    T = promote_eltype(itr, itrs...)
1,028✔
3138
    keep = intersect!(Set{T}(itr), itrs...)
1,028✔
3139
    vectorfilter(T, _shrink_filter!(keep), itr)
1,028✔
3140
end
3141

3142
function setdiff(itr, itrs...)
1,542✔
3143
    T = eltype(itr)
1,546✔
3144
    keep = setdiff!(Set{T}(itr), itrs...)
4,567✔
3145
    vectorfilter(T, _shrink_filter!(keep), itr)
1,546✔
3146
end
3147

3148
function intersect(v::AbstractVector, r::AbstractRange)
9✔
3149
    T = promote_eltype(v, r)
118✔
3150
    common = Iterators.filter(in(r), v)
118✔
3151
    seen = Set{T}(common)
118✔
3152
    return vectorfilter(T, _shrink_filter!(seen), common)
118✔
3153
end
3154
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
5✔
3155

3156
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3157
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
11,946✔
3158
    if i isa Bool # Not via dispatch to avoid ambiguities
1,925,392,759✔
3159
        throw(ArgumentError("invalid index: $i of type Bool"))
18✔
3160
    else
3161
        _getindex(v, i)
2,642,232,569✔
3162
    end
3163
end
3164

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

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

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

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

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

3193
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
6✔
3194
    dims = convert(Dims, dims)
6✔
3195
    ref = _wrap(memoryref(m), dims)
8✔
3196
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
4✔
3197
end
3198
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
8✔
3199
    dims = (Int(l),)
299,812✔
3200
    ref = _wrap(m, dims)
299,813✔
3201
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
298,921✔
3202
end
3203
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
2✔
3204
    dims = (Int(l),)
2✔
3205
    ref = _wrap(memoryref(m), (l,))
2✔
3206
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
2✔
3207
end
3208
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
213✔
3209
    ref = memoryref(m)
1,279,151✔
3210
    dims = (length(m),)
1,279,149✔
3211
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
1,235,052✔
3212
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