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

JuliaLang / julia / #37929

11 Oct 2024 05:57AM UTC coverage: 87.748% (-0.02%) from 87.764%
#37929

push

local

web-flow
Remove warning from c when binding is ambiguous (#56103)

78875 of 89888 relevant lines covered (87.75%)

16976924.6 hits per line

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

94.8
/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
19,920✔
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}()
654,829✔
159
function vect(X::T...) where T
50,744✔
160
    @_terminates_locally_meta
103,368✔
161
    vec = Vector{T}(undef, length(X))
1,743,165✔
162
    @_safeindex for i = 1:length(X)
240,297✔
163
        vec[i] = X[i]
4,855,310✔
164
    end
6,512,013✔
165
    return vec
189,011✔
166
end
167

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

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

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

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
4,932✔
190
    d < 1 && error("arraysize: dimension out of range")
65,405,034✔
191
    sz = getfield(a, :size)
65,525,295✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
89,724,270✔
193
end
194
size(a::Array) = getfield(a, :size)
2,147,483,647✔
195

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

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

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

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

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

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

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

223

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

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

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

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

252

253
## copy ##
254

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

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

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

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

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

278
The `unsafe` prefix on this function indicates that no validation is performed to ensure
279
that n is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
280
the same manner as C.
281
"""
282
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
283
    n == 0 && return dest
14,231,684✔
284
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
16,949,566✔
285
    return dest
8,474,786✔
286
end
287

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

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

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

301
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
11✔
302
    n == 0 && return dest
177,730,337✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
138,401,974✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
138,401,993✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
138,401,954✔
306
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
138,401,959✔
307
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
276,803,858✔
309
    end
310
    return dest
138,401,707✔
311
end
312

313

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

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

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

324
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
325
# for bootstrapping purposes.
326
function fill!(dest::Array{T}, x) where T
997✔
327
    @inline
269,081✔
328
    x = x isa T ? x : convert(T, x)::T
269,082✔
329
    return _fill!(dest, x)
2,147,483,647✔
330
end
331
function _fill!(dest::Array{T}, x::T) where T
332
    for i in eachindex(dest)
984,938,320✔
333
        @inbounds dest[i] = x
2,147,483,647✔
334
    end
2,147,483,647✔
335
    return dest
984,938,320✔
336
end
337

338
"""
339
    copy(x)
340

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

345
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
346
"""
347
copy
348

349
@eval function copy(a::Array{T}) where {T}
158,019✔
350
    # `jl_genericmemory_copy_slice` only throws when the size exceeds the max allocation
351
    # size, but since we're copying an existing array, we're guaranteed that this will not happen.
352
    @_nothrow_meta
281,017✔
353
    ref = a.ref
202,818,504✔
354
    newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a))
202,818,506✔
355
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
202,818,505✔
356
end
357

358
## Constructors ##
359

360
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
239,768✔
361
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
8,897✔
362
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
16,246✔
363
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
26,604✔
364
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
4,518,670✔
365
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
118,308,960✔
366
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
643✔
367

368
# T[x...] constructs Array{T,1}
369
"""
370
    getindex(type[, elements...])
371

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

375
# Examples
376
```jldoctest
377
julia> Int8[1, 2, 3]
378
3-element Vector{Int8}:
379
 1
380
 2
381
 3
382

383
julia> getindex(Int8, 1, 2, 3)
384
3-element Vector{Int8}:
385
 1
386
 2
387
 3
388
```
389
"""
390
function getindex(::Type{T}, vals...) where T
59,335✔
391
    @inline
189,271✔
392
    @_effect_free_terminates_locally_meta
189,271✔
393
    a = Vector{T}(undef, length(vals))
1,091,635,889✔
394
    if vals isa NTuple
189,303✔
395
        @_safeindex for i in 1:length(vals)
133,410✔
396
            a[i] = vals[i]
80,142,774✔
397
        end
243,802✔
398
    else
399
        # use afoldl to avoid type instability inside loop
400
        afoldl(1, vals...) do i, v
59,164✔
401
            @inbounds a[i] = v
124,488✔
402
            return i + 1
124,488✔
403
        end
404
    end
405
    return a
192,673✔
406
end
407

408
function getindex(::Type{Any}, @nospecialize vals...)
26,298,301✔
409
    @_effect_free_terminates_locally_meta
9,654✔
410
    a = Vector{Any}(undef, length(vals))
101,584,282✔
411
    @_safeindex for i = 1:length(vals)
33,754,954✔
412
        a[i] = vals[i]
135,987,749✔
413
    end
132,598,438✔
414
    return a
26,457,160✔
415
end
416
getindex(::Type{Any}) = Vector{Any}()
95,439,714✔
417

418
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
5✔
419
    ref = a.ref
203,719✔
420
    t = @_gc_preserve_begin ref
203,719✔
421
    p = unsafe_convert(Ptr{Cvoid}, ref)
203,719✔
422
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
203,722✔
423
    @_gc_preserve_end t
203,716✔
424
    return a
10,491✔
425
end
426

427
to_dim(d::Integer) = d
×
428
to_dim(d::OneTo) = last(d)
212✔
429

430
"""
431
    fill(value, dims::Tuple)
432
    fill(value, dims...)
433

434
Create an array of size `dims` with every location set to `value`.
435

436
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
437
with `1.0` in every location of the array.
438

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

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

452
```jldoctest
453
julia> v = fill([], 3)
454
3-element Vector{Vector{Any}}:
455
 []
456
 []
457
 []
458

459
julia> v[1] === v[2] === v[3]
460
true
461

462
julia> value = v[1]
463
Any[]
464

465
julia> push!(value, 867_5309)
466
1-element Vector{Any}:
467
 8675309
468

469
julia> v
470
3-element Vector{Vector{Any}}:
471
 [8675309]
472
 [8675309]
473
 [8675309]
474
```
475

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

479
```jldoctest
480
julia> v2 = [[] for _ in 1:3]
481
3-element Vector{Vector{Any}}:
482
 []
483
 []
484
 []
485

486
julia> v2[1] === v2[2] === v2[3]
487
false
488

489
julia> push!(v2[1], 8675309)
490
1-element Vector{Any}:
491
 8675309
492

493
julia> v2
494
3-element Vector{Vector{Any}}:
495
 [8675309]
496
 []
497
 []
498
```
499

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

502
# Examples
503
```jldoctest
504
julia> fill(1.0, (2,3))
505
2×3 Matrix{Float64}:
506
 1.0  1.0  1.0
507
 1.0  1.0  1.0
508

509
julia> fill(42)
510
0-dimensional Array{Int64, 0}:
511
42
512

513
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
514
2-element Vector{Vector{Float64}}:
515
 [0.0, 0.0]
516
 [0.0, 0.0]
517

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

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

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

534
"""
535
    zeros([T=Float64,] dims::Tuple)
536
    zeros([T=Float64,] dims...)
537

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

541
# Examples
542
```jldoctest
543
julia> zeros(1)
544
1-element Vector{Float64}:
545
 0.0
546

547
julia> zeros(Int8, 2, 3)
548
2×3 Matrix{Int8}:
549
 0  0  0
550
 0  0  0
551
```
552
"""
553
function zeros end
554

555
"""
556
    ones([T=Float64,] dims::Tuple)
557
    ones([T=Float64,] dims...)
558

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

562
# Examples
563
```jldoctest
564
julia> ones(1,2)
565
1×2 Matrix{Float64}:
566
 1.0  1.0
567

568
julia> ones(ComplexF64, 2, 3)
569
2×3 Matrix{ComplexF64}:
570
 1.0+0.0im  1.0+0.0im  1.0+0.0im
571
 1.0+0.0im  1.0+0.0im  1.0+0.0im
572
```
573
"""
574
function ones end
575

576
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
577
    @eval begin
578
        $fname(dims::DimOrInd...) = $fname(dims)
20,452,782✔
579
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
2,147,483,647✔
580
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,458,424✔
581
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,264✔
582
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
12,435✔
583
            a = Array{T,N}(undef, dims)
178,627,940✔
584
            fill!(a, $felt(T))
2,147,483,647✔
585
            return a
128,986,814✔
586
        end
587
        function $fname(::Type{T}, dims::Tuple{}) where {T}
588
            a = Array{T}(undef)
20✔
589
            fill!(a, $felt(T))
20✔
590
            return a
20✔
591
        end
592
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
66✔
593
            a = similar(Array{T,N}, dims)
66✔
594
            fill!(a, $felt(T))
132✔
595
            return a
66✔
596
        end
597
    end
598
end
599

600
## Conversions ##
601

602
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
292,533✔
603

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

606
## Constructors ##
607

608
if nameof(@__MODULE__) === :Base  # avoid method overwrite
609
# constructors should make copies
610
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
305,195✔
611
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
9,890✔
612
end
613

614
## copying iterators to containers
615

616
"""
617
    collect(element_type, collection)
618

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

622
# Examples
623
```jldoctest
624
julia> collect(Float64, 1:2:5)
625
3-element Vector{Float64}:
626
 1.0
627
 3.0
628
 5.0
629
```
630
"""
631
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
30,302,378✔
632

633
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
41,686✔
634
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
635
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
30,260,683✔
636
    a = Vector{T}()
30,260,692✔
637
    for x in itr
52,060,821✔
638
        push!(a, x)
147,891,833✔
639
    end
273,983,536✔
640
    return a
30,260,692✔
641
end
642

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

646
_similar_shape(itr, ::SizeUnknown) = nothing
×
647
_similar_shape(itr, ::HasLength) = length(itr)::Integer
51,293,246✔
648
_similar_shape(itr, ::HasShape) = axes(itr)
439,606,866✔
649

650
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,270,820✔
651
    similar(c, T, 0)
652
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
7,408,253✔
653
    similar(c, T, len)
654
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
295,085✔
655
    similar(c, T, axs)
656

657
# make a collection appropriate for collecting `itr::Generator`
658
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
257✔
659
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
71,857,299✔
660
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
1,215,816,678✔
661

662
# used by syntax lowering for simple typed comprehensions
663
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
1,286,010,213✔
664

665

666
"""
667
    collect(iterator)
668

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

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

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

681
# Examples
682

683
Collect items from a `UnitRange{Int64}` collection:
684

685
```jldoctest
686
julia> collect(1:3)
687
3-element Vector{Int64}:
688
 1
689
 2
690
 3
691
```
692

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

695
```jldoctest
696
julia> collect(x^2 for x in 1:3)
697
3-element Vector{Int64}:
698
 1
699
 4
700
 9
701
```
702

703
Collecting an empty iterator where the result type depends on type inference:
704

705
```jldoctest
706
julia> [rand(Bool) ? 1 : missing for _ in []]
707
Union{Missing, Int64}[]
708
```
709

710
When the iterator is non-empty, the result type depends only on values:
711

712
```julia-repl
713
julia> [rand(Bool) ? 1 : missing for _ in [""]]
714
1-element Vector{Int64}:
715
 1
716
```
717
"""
718
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
8,910,306✔
719

720
collect(A::AbstractArray) = _collect_indices(axes(A), A)
130,965✔
721

722
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
189,315✔
723

724
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
7,394,803✔
725
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
726

727
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,270,750✔
728
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,270,782✔
729
    for x in itr
2,539,497✔
730
        push!(a,x)
10,207,347✔
731
    end
17,501,589✔
732
    return a
1,270,781✔
733
end
734

735
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
736
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
132,341✔
737
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
738
function _collect_indices(indsA, A)
36✔
739
    B = Array{eltype(A)}(undef, length.(indsA))
237✔
740
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
741
end
742

743
# NOTE: this function is not meant to be called, only inferred, for the
744
# purpose of bounding the types of values generated by an iterator.
745
function _iterator_upper_bound(itr)
×
746
    x = iterate(itr)
×
747
    while x !== nothing
×
748
        val = getfield(x, 1)
×
749
        if inferencebarrier(nothing)
×
750
            return val
×
751
        end
752
        x = iterate(itr, getfield(x, 2))
×
753
    end
×
754
    throw(nothing)
×
755
end
756

757
# define this as a macro so that the call to Core.Compiler
758
# gets inlined into the caller before recursion detection
759
# gets a chance to see it, so that recursive calls to the caller
760
# don't trigger the inference limiter
761
if isdefined(Core, :Compiler)
762
    macro default_eltype(itr)
763
        I = esc(itr)
764
        return quote
765
            if $I isa Generator && ($I).f isa Type
541,905✔
766
                T = ($I).f
12,745✔
767
            else
768
                T = Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)})
529,160✔
769
            end
770
            promote_typejoin_union(T)
541,909✔
771
        end
772
    end
773
else
774
    macro default_eltype(itr)
775
        I = esc(itr)
776
        return quote
777
            if $I isa Generator && ($I).f isa Type
778
                promote_typejoin_union($I.f)
779
            else
780
                Any
781
            end
782
        end
783
    end
784
end
785

786
function collect(itr::Generator)
913,411✔
787
    isz = IteratorSize(itr.iter)
394,037✔
788
    et = @default_eltype(itr)
789
    if isa(isz, SizeUnknown)
394,037✔
790
        return grow_to!(Vector{et}(), itr)
100,419✔
791
    else
792
        shp = _similar_shape(itr, isz)
824,212✔
793
        y = iterate(itr)
1,635,847✔
794
        if y === nothing
823,586✔
795
            return _array_for(et, isz, shp)
947✔
796
        end
797
        v1, st = y
392,098✔
798
        dest = _array_for(typeof(v1), isz, shp)
1,633,406✔
799
        # The typeassert gives inference a helping hand on the element type and dimensionality
800
        # (work-around for #28382)
801
        et′ = et <: Type ? Type : et
392,098✔
802
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
392,248✔
803
        collect_to_with_first!(dest, v1, itr, st)::RT
10,812,643✔
804
    end
805
end
806

807
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
38✔
808
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
809

810
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
189,336✔
811
    et = @default_eltype(itr)
125,413✔
812
    shp = _similar_shape(itr, isz)
189,343✔
813
    y = iterate(itr)
377,217✔
814
    if y === nothing
189,341✔
815
        return _similar_for(c, et, itr, isz, shp)
1,442✔
816
    end
817
    v1, st = y
124,250✔
818
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
292,018✔
819
    # The typeassert gives inference a helping hand on the element type and dimensionality
820
    # (work-around for #28382)
821
    et′ = et <: Type ? Type : et
124,228✔
822
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
124,241✔
823
    collect_to_with_first!(dest, v1, itr, st)::RT
187,899✔
824
end
825

826
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
86,687✔
827
    i1 = first(LinearIndices(dest))
516,326✔
828
    dest[i1] = v1
1,010,538✔
829
    return collect_to!(dest, itr, i1+1, st)
11,665,198✔
830
end
831

832
function collect_to_with_first!(dest, v1, itr, st)
×
833
    push!(dest, v1)
×
834
    return grow_to!(dest, itr, st)
×
835
end
836

837
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
204✔
838
    @inline
334✔
839
    new = similar(dest, promote_typejoin(T, typeof(el)))
756✔
840
    f = first(LinearIndices(dest))
334✔
841
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
753✔
842
    @inbounds new[i] = el
379✔
843
    return new
379✔
844
end
845

846
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
129,690✔
847
    # collect to dest array, checking the type of each result. if a result does not
848
    # match, widen the result type and re-dispatch.
849
    i = offs
516,660✔
850
    while true
92,436,404✔
851
        y = iterate(itr, st)
183,862,240✔
852
        y === nothing && break
92,436,394✔
853
        el, st = y
90,450,626✔
854
        if el isa T
90,461,316✔
855
            @inbounds dest[i] = el
91,425,487✔
856
            i += 1
91,425,487✔
857
        else
858
            new = setindex_widen_up_to(dest, el, i)
379✔
859
            return collect_to!(new, itr, i+1, st)
379✔
860
        end
861
    end
91,425,487✔
862
    return dest
1,010,528✔
863
end
864

865
function grow_to!(dest, itr)
1,205✔
866
    y = iterate(itr)
1,522✔
867
    y === nothing && return dest
1,243✔
868
    dest2 = empty(dest, typeof(y[1]))
307✔
869
    push!(dest2, y[1])
355✔
870
    grow_to!(dest2, itr, y[2])
285✔
871
end
872

873
function push_widen(dest, el)
7✔
874
    @inline
10✔
875
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
11✔
876
    if new isa AbstractSet
10✔
877
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
878
        union!(new, dest)
1✔
879
    else
880
        append!(new, dest)
18✔
881
    end
882
    push!(new, el)
10✔
883
    return new
10✔
884
end
885

886
function grow_to!(dest, itr, st)
280✔
887
    T = eltype(dest)
173✔
888
    y = iterate(itr, st)
496✔
889
    while y !== nothing
3,978✔
890
        el, st = y
2,347✔
891
        if el isa T
2,349✔
892
            push!(dest, el)
3,686✔
893
        else
894
            new = push_widen(dest, el)
13✔
895
            return grow_to!(new, itr, st)
10✔
896
        end
897
        y = iterate(itr, st)
5,726✔
898
    end
3,683✔
899
    return dest
285✔
900
end
901

902
## Iteration ##
903

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

906
## Indexing: getindex ##
907

908
"""
909
    getindex(collection, key...)
910

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

914
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
915

916
# Examples
917
```jldoctest
918
julia> A = Dict("a" => 1, "b" => 2)
919
Dict{String, Int64} with 2 entries:
920
  "b" => 2
921
  "a" => 1
922

923
julia> getindex(A, "a")
924
1
925
```
926
"""
927
function getindex end
928

929
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
120,847✔
930
    @inline
199,922,270✔
931
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
212,469,043✔
932
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
212,469,411✔
933
end
934

935
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
936
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
9,310,476✔
937
    @inline
869,465✔
938
    @boundscheck checkbounds(A, I)
74,587,793✔
939
    lI = length(I)
74,587,802✔
940
    X = similar(A, axes(I))
117,247,153✔
941
    if lI > 0
74,587,791✔
942
        copyto!(X, firstindex(X), A, first(I), lI)
85,318,712✔
943
    end
944
    return X
74,587,791✔
945
end
946

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

950
function getindex(A::Array, c::Colon)
4,450✔
951
    lI = length(A)
2,256,941✔
952
    X = similar(A, lI)
4,513,880✔
953
    if lI > 0
2,256,941✔
954
        unsafe_copyto!(X, 1, A, 1, lI)
4,513,878✔
955
    end
956
    return X
2,256,941✔
957
end
958

959
# This is redundant with the abstract fallbacks, but needed for bootstrap
960
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
141✔
961
    return S[ A[i] for i in I ]
13,030,949✔
962
end
963

964
## Indexing: setindex! ##
965

966
"""
967
    setindex!(collection, value, key...)
968

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

972
# Examples
973
```jldoctest
974
julia> a = Dict("a"=>1)
975
Dict{String, Int64} with 1 entry:
976
  "a" => 1
977

978
julia> setindex!(a, 2, "b")
979
Dict{String, Int64} with 2 entries:
980
  "b" => 2
981
  "a" => 1
982
```
983
"""
984
function setindex! end
985

986
function setindex!(A::Array{T}, x, i::Int) where {T}
21,449,815✔
987
    @_propagate_inbounds_meta
722,136,074✔
988
    x = x isa T ? x : convert(T, x)::T
1,800,013,291✔
989
    return _setindex!(A, x, i)
2,147,483,647✔
990
end
991
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
992
    @_noub_if_noinbounds_meta
712,894,215✔
993
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
2,147,483,647✔
994
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
2,147,483,647✔
995
    return A
2,147,483,647✔
996
end
997
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,511✔
998
    @_propagate_inbounds_meta
72,479,729✔
999
    x = x isa T ? x : convert(T, x)::T
72,480,627✔
1000
    return _setindex!(A, x, i1, i2, I...)
75,659,707✔
1001
end
1002
function _setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
4✔
1003
    @inline
72,473,845✔
1004
    @_noub_if_noinbounds_meta
72,473,845✔
1005
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
75,659,737✔
1006
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
75,659,719✔
1007
    return A
75,659,719✔
1008
end
1009

1010
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
1,691,496✔
1011
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
418,792,948✔
1012
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
490,788✔
1013
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
2,147,483,647✔
1014
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
1015
    __safe_setindex!(A, convert(T, x)::T, i))
36,105✔
1016

1017
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1018
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
91✔
1019
    @_propagate_inbounds_meta
816,857✔
1020
    @boundscheck setindex_shape_check(X, length(I))
9,996,610✔
1021
    @boundscheck checkbounds(A, I)
9,996,610✔
1022
    require_one_based_indexing(X)
816,857✔
1023
    X′ = unalias(A, X)
816,857✔
1024
    I′ = unalias(A, I)
816,857✔
1025
    count = 1
816,857✔
1026
    for i in I′
9,996,870✔
1027
        @inbounds A[i] = X′[count]
22,924,316✔
1028
        count += 1
22,924,316✔
1029
    end
37,313,116✔
1030
    return A
9,996,610✔
1031
end
1032

1033
# Faster contiguous setindex! with copyto!
1034
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
109✔
1035
    @inline
1,008,712✔
1036
    @boundscheck checkbounds(A, I)
1,009,026✔
1037
    lI = length(I)
1,009,026✔
1038
    @boundscheck setindex_shape_check(X, lI)
1,009,026✔
1039
    if lI > 0
1,009,026✔
1040
        unsafe_copyto!(A, first(I), X, 1, lI)
2,017,502✔
1041
    end
1042
    return A
1,009,026✔
1043
end
1044
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
40✔
1045
    @inline
74✔
1046
    lI = length(A)
74✔
1047
    @boundscheck setindex_shape_check(X, lI)
74✔
1048
    if lI > 0
74✔
1049
        unsafe_copyto!(A, 1, X, 1, lI)
148✔
1050
    end
1051
    return A
74✔
1052
end
1053

1054
# Pick new memory size for efficiently growing an array
1055
# TODO: This should know about the size of our GC pools
1056
# Specifically we are wasting ~10% of memory for small arrays
1057
# by not picking memory sizes that max out a GC pool
1058
function overallocation(maxsize)
1059
    maxsize < 8 && return 8;
1,386,860,584✔
1060
    # compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
1061
    # for small n, we grow faster than O(n)
1062
    # for large n, we grow at O(n/8)
1063
    # and as we reach O(memory) for memory>>1MB,
1064
    # this means we end by adding about 10% of memory each time
1065
    exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
97,583,868✔
1066
    maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8)
97,583,868✔
1067
    return maxsize
97,583,868✔
1068
end
1069

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

1072
function _growbeg!(a::Vector, delta::Integer)
38✔
1073
    @_noub_meta
19,145✔
1074
    delta = Int(delta)
19,145✔
1075
    delta == 0 && return # avoid attempting to index off the end
27,605,503✔
1076
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
27,604,931✔
1077
    ref = a.ref
82,471,201✔
1078
    mem = ref.mem
82,471,201✔
1079
    len = length(a)
82,471,201✔
1080
    offset = memoryrefoffset(ref)
82,471,201✔
1081
    newlen = len + delta
82,471,201✔
1082
    setfield!(a, :size, (newlen,))
82,471,201✔
1083
    # if offset is far enough advanced to fit data in existing memory without copying
1084
    if delta <= offset - 1
82,471,201✔
1085
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
53,718,042✔
1086
    else
1087
        @noinline (function()
57,507,532✔
1088
        @_terminates_locally_meta
11,932✔
1089
        memlen = length(mem)
28,754,374✔
1090
        if offset + len - 1 > memlen || offset < 1
57,508,748✔
1091
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1092
        end
1093
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1094
        # the +1 is because I didn't want to have an off by 1 error.
1095
        newmemlen = max(overallocation(len), len + 2 * delta + 1)
43,469,618✔
1096
        newoffset = div(newmemlen - newlen, 2) + 1
28,754,374✔
1097
        # If there is extra data after the end of the array we can use that space so long as there is enough
1098
        # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1099
        # Specifically, we want to ensure that we will only do this operation once before
1100
        # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1101
        if newoffset + newlen < memlen
28,754,374✔
1102
            newoffset = div(memlen - newlen, 2) + 1
25,504✔
1103
            newmem = mem
25,504✔
1104
            unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
46,895✔
1105
            for j in offset:newoffset+delta-1
25,504✔
1106
                @inbounds _unsetindex!(mem, j)
162,238✔
1107
            end
285,228✔
1108
        else
1109
            newmem = array_new_memory(mem, newmemlen)
57,457,740✔
1110
            unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
28,728,870✔
1111
        end
1112
        if ref !== a.ref
28,754,374✔
1113
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1114
        end
1115
        setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
28,754,374✔
1116
        end)()
1117
    end
1118
    return
82,471,201✔
1119
end
1120

1121
function _growend!(a::Vector, delta::Integer)
26✔
1122
    @_noub_meta
4,247,661✔
1123
    delta = Int(delta)
4,266,908✔
1124
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,354,573,662✔
1125
    ref = a.ref
2,147,483,647✔
1126
    mem = ref.mem
2,147,483,647✔
1127
    memlen = length(mem)
2,147,483,647✔
1128
    len = length(a)
2,147,483,647✔
1129
    newlen = len + delta
2,147,483,647✔
1130
    offset = memoryrefoffset(ref)
2,147,483,647✔
1131
    setfield!(a, :size, (newlen,))
2,147,483,647✔
1132
    newmemlen = offset + newlen - 1
2,147,483,647✔
1133
    if memlen < newmemlen
2,147,483,647✔
1134
        @noinline (function()
2,147,483,647✔
1135
        if offset + len - 1 > memlen || offset < 1
2,147,483,647✔
1136
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1137
        end
1138

1139
        if offset - 1 > div(5 * newlen, 4)
1,336,063,515✔
1140
            # If the offset is far enough that we can copy without resizing
1141
            # while maintaining proportional spacing on both ends of the array
1142
            # note that this branch prevents infinite growth when doing combinations
1143
            # of push! and popfirst! (i.e. when using a Vector as a queue)
1144
            newmem = mem
23,514✔
1145
            newoffset = div(newlen, 8) + 1
23,514✔
1146
        else
1147
            # grow either by our computed overallocation factor
1148
            # or exactly the requested size, whichever is larger
1149
            # TODO we should possibly increase the offset if the current offset is nonzero.
1150
            newmemlen2 = max(overallocation(memlen), newmemlen)
1,410,235,280✔
1151
            newmem = array_new_memory(mem, newmemlen2)
2,147,483,647✔
1152
            newoffset = offset
1,336,040,001✔
1153
        end
1154
        newref = @inbounds memoryref(newmem, newoffset)
1,336,063,515✔
1155
        unsafe_copyto!(newref, ref, len)
1,455,892,732✔
1156
        if ref !== a.ref
1,336,063,515✔
1157
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1158
        end
1159
        setfield!(a, :ref, newref)
1,336,063,515✔
1160
        end)()
1161
    end
1162
    return
2,147,483,647✔
1163
end
1164

1165
function _growat!(a::Vector, i::Integer, delta::Integer)
115,561,716✔
1166
    @_terminates_globally_noub_meta
165,554✔
1167
    delta = Int(delta)
165,554✔
1168
    i = Int(i)
165,554✔
1169
    i == 1 && return _growbeg!(a, delta)
115,561,716✔
1170
    len = length(a)
88,363,303✔
1171
    i == len + 1 && return _growend!(a, delta)
88,363,303✔
1172
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
88,297,660✔
1173
    1 < i <= len || throw(BoundsError(a, i))
88,297,662✔
1174
    ref = a.ref
88,297,658✔
1175
    mem = ref.mem
88,297,658✔
1176
    memlen = length(mem)
88,297,658✔
1177
    newlen = len + delta
88,297,658✔
1178
    offset = memoryrefoffset(ref)
88,297,658✔
1179
    setfield!(a, :size, (newlen,))
88,297,658✔
1180
    newmemlen = offset + newlen - 1
88,297,658✔
1181

1182
    # which side would we rather grow into?
1183
    prefer_start = i <= div(len, 2)
88,297,658✔
1184
    # if offset is far enough advanced to fit data in beginning of the memory
1185
    if prefer_start && delta <= offset - 1
88,297,658✔
1186
        newref = @inbounds memoryref(mem, offset - delta)
36,367,760✔
1187
        unsafe_copyto!(newref, ref, i)
72,735,520✔
1188
        setfield!(a, :ref, newref)
36,367,760✔
1189
        for j in i:i+delta-1
36,367,760✔
1190
            @inbounds _unsetindex!(a, j)
51,268,563✔
1191
        end
51,261,732✔
1192
    elseif !prefer_start && memlen >= newmemlen
51,929,898✔
1193
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
74,816,184✔
1194
        for j in i:i+delta-1
37,408,092✔
1195
            @inbounds _unsetindex!(a, j)
51,934,579✔
1196
        end
51,925,464✔
1197
    else
1198
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1199
        # the +1 is because I didn't want to have an off by 1 error.
1200
        newmemlen = max(overallocation(memlen), len+2*delta+1)
21,261,908✔
1201
        newoffset = (newmemlen - newlen) ÷ 2 + 1
14,521,806✔
1202
        newmem = array_new_memory(mem, newmemlen)
29,043,612✔
1203
        newref = @inbounds memoryref(newmem, newoffset)
14,521,806✔
1204
        unsafe_copyto!(newref, ref, i-1)
29,043,612✔
1205
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
29,043,612✔
1206
        setfield!(a, :ref, newref)
14,521,806✔
1207
    end
1208
end
1209

1210
# efficiently delete part of an array
1211
function _deletebeg!(a::Vector, delta::Integer)
22,912,167✔
1212
    delta = Int(delta)
1,081,295✔
1213
    len = length(a)
84,335,949✔
1214
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
84,335,949✔
1215
    for i in 1:delta
24,097,864✔
1216
        @inbounds _unsetindex!(a, i)
113,326,172✔
1217
    end
36,173,932✔
1218
    newlen = len - delta
84,335,949✔
1219
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
84,335,949✔
1220
        newref = @inbounds memoryref(a.ref, delta + 1)
76,661,192✔
1221
        setfield!(a, :ref, newref)
76,661,192✔
1222
    end
1223
    setfield!(a, :size, (newlen,))
84,335,949✔
1224
    return
84,335,949✔
1225
end
1226
function _deleteend!(a::Vector, delta::Integer)
25,159,872✔
1227
    delta = Int(delta)
6,535,982✔
1228
    len = length(a)
1,822,214,007✔
1229
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
1,822,214,007✔
1230
    newlen = len - delta
1,822,214,007✔
1231
    for i in newlen+1:len
1,869,104,299✔
1232
        @inbounds _unsetindex!(a, i)
2,147,483,647✔
1233
    end
2,147,483,647✔
1234
    setfield!(a, :size, (newlen,))
1,822,214,007✔
1235
    return
1,822,214,007✔
1236
end
1237
function _deleteat!(a::Vector, i::Integer, delta::Integer)
8,892,172✔
1238
    i = Int(i)
100,996✔
1239
    len = length(a)
8,892,172✔
1240
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
8,892,172✔
1241
    1 <= i <= len || throw(BoundsError(a, i))
8,892,175✔
1242
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
8,892,169✔
1243
    newa = a
100,983✔
1244
    if 2*i + delta <= len
8,892,169✔
1245
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
173,212✔
1246
        _deletebeg!(a, delta)
3,545,668✔
1247
    else
1248
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
11,858,870✔
1249
        _deleteend!(a, delta)
8,766,000✔
1250
    end
1251
    return
8,892,169✔
1252
end
1253
## Dequeue functionality ##
1254

1255
"""
1256
    push!(collection, items...) -> collection
1257

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

1261
# Examples
1262
```jldoctest
1263
julia> push!([1, 2, 3], 4, 5, 6)
1264
6-element Vector{Int64}:
1265
 1
1266
 2
1267
 3
1268
 4
1269
 5
1270
 6
1271
```
1272

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

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

1279
See also [`pushfirst!`](@ref).
1280
"""
1281
function push! end
1282

1283
function push!(a::Vector{T}, item) where T
4,612,422✔
1284
    @inline
9,440,787✔
1285
    # convert first so we don't grow the array if the assignment won't work
1286
    # and also to avoid a dynamic dynamic dispatch in the common case that
1287
    # `item` is poorly-typed and `a` is well-typed
1288
    item = item isa T ? item : convert(T, item)::T
50,511,690✔
1289
    return _push!(a, item)
2,147,483,647✔
1290
end
1291
function _push!(a::Vector{T}, item::T) where T
1292
    _growend!(a, 1)
2,147,483,647✔
1293
    @_safeindex a[length(a)] = item
2,147,483,647✔
1294
    return a
2,147,483,647✔
1295
end
1296

1297
# specialize and optimize the single argument case
1298
function push!(a::Vector{Any}, @nospecialize x)
8,256✔
1299
    _growend!(a, 1)
227,478,093✔
1300
    @_safeindex a[length(a)] = x
227,478,093✔
1301
    return a
227,478,093✔
1302
end
1303
function push!(a::Vector{Any}, @nospecialize x...)
16✔
1304
    @_terminates_locally_meta
17✔
1305
    na = length(a)
351,869✔
1306
    nx = length(x)
17✔
1307
    _growend!(a, nx)
351,869✔
1308
    @_safeindex for i = 1:nx
703,721✔
1309
        a[na+i] = x[i]
921,902✔
1310
    end
1,055,721✔
1311
    return a
351,869✔
1312
end
1313

1314
"""
1315
    append!(collection, collections...) -> collection.
1316

1317
For an ordered container `collection`, add the elements of each `collections`
1318
to the end of it.
1319

1320
!!! compat "Julia 1.6"
1321
    Specifying multiple collections to be appended requires at least Julia 1.6.
1322

1323
# Examples
1324
```jldoctest
1325
julia> append!([1], [2, 3])
1326
3-element Vector{Int64}:
1327
 1
1328
 2
1329
 3
1330

1331
julia> append!([1, 2, 3], [4, 5], [6])
1332
6-element Vector{Int64}:
1333
 1
1334
 2
1335
 3
1336
 4
1337
 5
1338
 6
1339
```
1340

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

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

1347
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1348
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1349
"""
1350
function append! end
1351

1352
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
8,434✔
1353
    items isa Tuple && (items = map(x -> convert(T, x), items))
2,250,053✔
1354
    n = length(items)
89,731,124✔
1355
    _growend!(a, n)
90,301,816✔
1356
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
139,967,574✔
1357
    return a
90,301,816✔
1358
end
1359

1360
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
91,605,772✔
1361
push!(a::AbstractVector, iter...) = append!(a, iter)
1,309,956✔
1362
append!(a::AbstractVector, iter...) = (for v in iter; append!(a, v); end; return a)
7✔
1363

1364
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
29,181,268✔
1365
    n = Int(length(iter))::Int
29,416,364✔
1366
    i = lastindex(a)
38✔
1367
    sizehint!(a, length(a) + n; shrink=false)
29,181,281✔
1368
    for item in iter
48,501,593✔
1369
        push!(a, item)
52,817,632✔
1370
    end
53,050,733✔
1371
    a
21✔
1372
end
1373
function _append!(a::AbstractVector, ::IteratorSize, iter)
62,424,488✔
1374
    for item in iter
76,324,188✔
1375
        push!(a, item)
62,268,233✔
1376
    end
62,268,239✔
1377
    a
4✔
1378
end
1379

1380
"""
1381
    prepend!(a::Vector, collections...) -> collection
1382

1383
Insert the elements of each `collections` to the beginning of `a`.
1384

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

1388
!!! compat "Julia 1.6"
1389
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1390

1391
# Examples
1392
```jldoctest
1393
julia> prepend!([3], [1, 2])
1394
3-element Vector{Int64}:
1395
 1
1396
 2
1397
 3
1398

1399
julia> prepend!([6], [1, 2], [3, 4, 5])
1400
6-element Vector{Int64}:
1401
 1
1402
 2
1403
 3
1404
 4
1405
 5
1406
 6
1407
```
1408
"""
1409
function prepend! end
1410

1411
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
2,154✔
1412
    items isa Tuple && (items = map(x -> convert(T, x), items))
5,122✔
1413
    n = length(items)
7,284✔
1414
    _growbeg!(a, n)
13,995✔
1415
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1416
    # just the last n elements instead of all of them from the first
1417
    copyto!(a, 1, items, lastindex(items)-n+1, n)
13,990✔
1418
    return a
7,284✔
1419
end
1420

1421
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
481✔
1422
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
15✔
1423
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
7✔
1424

1425
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
461✔
1426
    @_terminates_locally_meta
462✔
1427
    require_one_based_indexing(a)
462✔
1428
    n = Int(length(iter))::Int
462✔
1429
    sizehint!(a, length(a) + n; first=true, shrink=false)
462✔
1430
    n = 0
462✔
1431
    for item in iter
463✔
1432
        n += 1
761✔
1433
        pushfirst!(a, item)
762✔
1434
    end
757✔
1435
    reverse!(a, 1, n)
456✔
1436
    a
456✔
1437
end
1438
function _prepend!(a::Vector, ::IteratorSize, iter)
3✔
1439
    n = 0
3✔
1440
    for item in iter
5✔
1441
        n += 1
8✔
1442
        pushfirst!(a, item)
11✔
1443
    end
13✔
1444
    reverse!(a, 1, n)
2✔
1445
    a
2✔
1446
end
1447

1448
"""
1449
    resize!(a::Vector, n::Integer) -> Vector
1450

1451
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1452
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1453
guaranteed to be initialized.
1454

1455
# Examples
1456
```jldoctest
1457
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1458
3-element Vector{Int64}:
1459
 6
1460
 5
1461
 4
1462

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

1465
julia> length(a)
1466
8
1467

1468
julia> a[1:6]
1469
6-element Vector{Int64}:
1470
 6
1471
 5
1472
 4
1473
 3
1474
 2
1475
 1
1476
```
1477
"""
1478
function resize!(a::Vector, nl::Integer)
1,482,773,616✔
1479
    l = length(a)
1,548,151,843✔
1480
    if nl > l
1,548,151,843✔
1481
        _growend!(a, nl-l)
1,043,266,223✔
1482
    elseif nl != l
504,885,620✔
1483
        if nl < 0
131,662,404✔
1484
            _throw_argerror("new length must be ≥ 0")
2✔
1485
        end
1486
        _deleteend!(a, l-nl)
131,662,402✔
1487
    end
1488
    return a
1,548,151,841✔
1489
end
1490

1491
"""
1492
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1493

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

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

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

1507
See also [`resize!`](@ref).
1508

1509
# Notes on the performance model
1510

1511
For types that support `sizehint!`,
1512

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

1517
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1518
   `Base`.
1519

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

1522
!!! compat "Julia 1.11"
1523
    The `shrink` and `first` arguments were added in Julia 1.11.
1524
"""
1525
function sizehint! end
1526

1527
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
58,622,594✔
1528
    len = length(a)
29,310,521✔
1529
    ref = a.ref
29,310,521✔
1530
    mem = ref.mem
29,310,521✔
1531
    memlen = length(mem)
29,310,521✔
1532
    sz = max(Int(sz), len)
29,310,521✔
1533
    inc = sz - len
29,310,521✔
1534
    if sz <= memlen
29,310,521✔
1535
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1536
        if !shrink || memlen - sz <= div(memlen, 8)
25,646,901✔
1537
            return a
25,437,184✔
1538
        end
1539
        newmem = array_new_memory(mem, sz)
140,908✔
1540
        if first
96,202✔
1541
            newref = memoryref(newmem, inc + 1)
×
1542
        else
1543
            newref = memoryref(newmem)
96,202✔
1544
        end
1545
        unsafe_copyto!(newref, ref, len)
160,237✔
1546
        setfield!(a, :ref, newref)
96,202✔
1547
    elseif first
3,777,135✔
1548
        _growbeg!(a, inc)
914✔
1549
        newref = getfield(a, :ref)
457✔
1550
        newref = memoryref(newref, inc + 1)
457✔
1551
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
457✔
1552
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
457✔
1553
    else # last
1554
        _growend!(a, inc)
3,776,678✔
1555
        setfield!(a, :size, (len,)) # undo the size change from _growend!
3,776,678✔
1556
    end
1557
    a
6,826✔
1558
end
1559

1560
# Fall-back implementation for non-shrinkable collections
1561
# avoid defining this the normal way to avoid avoid infinite recursion
1562
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
2✔
1563
    get(kwargs, :first, false)::Bool
219✔
1564
    get(kwargs, :shrink, true)::Bool
219✔
1565
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
219✔
1566
    sizehint!(a, sz)
219✔
1567
end
1568

1569
"""
1570
    pop!(collection) -> item
1571

1572
Remove an item in `collection` and return it. If `collection` is an
1573
ordered container, the last item is returned; for unordered containers,
1574
an arbitrary element is returned.
1575

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

1578
# Examples
1579
```jldoctest
1580
julia> A=[1, 2, 3]
1581
3-element Vector{Int64}:
1582
 1
1583
 2
1584
 3
1585

1586
julia> pop!(A)
1587
3
1588

1589
julia> A
1590
2-element Vector{Int64}:
1591
 1
1592
 2
1593

1594
julia> S = Set([1, 2])
1595
Set{Int64} with 2 elements:
1596
  2
1597
  1
1598

1599
julia> pop!(S)
1600
2
1601

1602
julia> S
1603
Set{Int64} with 1 element:
1604
  1
1605

1606
julia> pop!(Dict(1=>2))
1607
1 => 2
1608
```
1609
"""
1610
function pop!(a::Vector)
22,337✔
1611
    if isempty(a)
1,586,875,899✔
1612
        _throw_argerror("array must be non-empty")
1✔
1613
    end
1614
    item = a[end]
1,586,875,898✔
1615
    _deleteend!(a, 1)
1,586,875,898✔
1616
    return item
1,586,875,898✔
1617
end
1618

1619
"""
1620
    popat!(a::Vector, i::Integer, [default])
1621

1622
Remove the item at the given `i` and return it. Subsequent items
1623
are shifted to fill the resulting gap.
1624
When `i` is not a valid index for `a`, return `default`, or throw an error if
1625
`default` is not specified.
1626

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

1629
!!! compat "Julia 1.5"
1630
    This function is available as of Julia 1.5.
1631

1632
# Examples
1633
```jldoctest
1634
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1635
3
1636

1637
julia> a
1638
3-element Vector{Int64}:
1639
 4
1640
 2
1641
 1
1642

1643
julia> popat!(a, 4, missing)
1644
missing
1645

1646
julia> popat!(a, 4)
1647
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1648
[...]
1649
```
1650
"""
1651
function popat!(a::Vector, i::Integer)
4✔
1652
    x = a[i]
10✔
1653
    _deleteat!(a, i, 1)
4✔
1654
    x
4✔
1655
end
1656

1657
function popat!(a::Vector, i::Integer, default)
2✔
1658
    if 1 <= i <= length(a)
2✔
1659
        x = @inbounds a[i]
1✔
1660
        _deleteat!(a, i, 1)
1✔
1661
        x
1✔
1662
    else
1663
        default
1✔
1664
    end
1665
end
1666

1667
"""
1668
    pushfirst!(collection, items...) -> collection
1669

1670
Insert one or more `items` at the beginning of `collection`.
1671

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

1674
# Examples
1675
```jldoctest
1676
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1677
6-element Vector{Int64}:
1678
 5
1679
 6
1680
 1
1681
 2
1682
 3
1683
 4
1684
```
1685
"""
1686
function pushfirst!(a::Vector{T}, item) where T
309✔
1687
    @inline
2,948✔
1688
    item = item isa T ? item : convert(T, item)::T
2,951✔
1689
    return _pushfirst!(a, item)
38,128✔
1690
end
1691
function _pushfirst!(a::Vector{T}, item::T) where T
1692
    _growbeg!(a, 1)
38,354✔
1693
    @_safeindex a[1] = item
35,101✔
1694
    return a
35,101✔
1695
end
1696

1697
# specialize and optimize the single argument case
1698
function pushfirst!(a::Vector{Any}, @nospecialize x)
26,809,342✔
1699
    _growbeg!(a, 1)
56,046,330✔
1700
    @_safeindex a[1] = x
54,833,016✔
1701
    return a
54,833,016✔
1702
end
1703
function pushfirst!(a::Vector{Any}, @nospecialize x...)
1✔
1704
    @_terminates_locally_meta
2✔
1705
    na = length(a)
2✔
1706
    nx = length(x)
2✔
1707
    _growbeg!(a, nx)
1,348✔
1708
    @_safeindex for i = 1:nx
1,346✔
1709
        a[i] = x[i]
1,350✔
1710
    end
2,026✔
1711
    return a
674✔
1712
end
1713

1714
"""
1715
    popfirst!(collection) -> item
1716

1717
Remove the first `item` from `collection`.
1718

1719
This function is called `shift` in many other programming languages.
1720

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

1723
# Examples
1724
```jldoctest
1725
julia> A = [1, 2, 3, 4, 5, 6]
1726
6-element Vector{Int64}:
1727
 1
1728
 2
1729
 3
1730
 4
1731
 5
1732
 6
1733

1734
julia> popfirst!(A)
1735
1
1736

1737
julia> A
1738
5-element Vector{Int64}:
1739
 2
1740
 3
1741
 4
1742
 5
1743
 6
1744
```
1745
"""
1746
function popfirst!(a::Vector)
26,809,651✔
1747
    if isempty(a)
84,181,911✔
1748
        _throw_argerror("array must be non-empty")
1✔
1749
    end
1750
    item = a[1]
84,181,910✔
1751
    _deletebeg!(a, 1)
84,181,910✔
1752
    return item
84,181,910✔
1753
end
1754

1755
"""
1756
    insert!(a::Vector, index::Integer, item)
1757

1758
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1759
the resulting `a`.
1760

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

1763
# Examples
1764
```jldoctest
1765
julia> insert!(Any[1:6;], 3, "here")
1766
7-element Vector{Any}:
1767
 1
1768
 2
1769
  "here"
1770
 3
1771
 4
1772
 5
1773
 6
1774
```
1775
"""
1776
function insert!(a::Array{T,1}, i::Integer, item) where T
299✔
1777
    @_propagate_inbounds_meta
1,190,053✔
1778
    item = item isa T ? item : convert(T, item)::T
1,190,093✔
1779
    return _insert!(a, i, item)
92,707,618✔
1780
end
1781
function _insert!(a::Array{T,1}, i::Integer, item::T) where T
1782
    @_noub_meta
1,190,017✔
1783
    # Throw convert error before changing the shape of the array
1784
    _growat!(a, i, 1)
92,707,618✔
1785
    # :noub, because _growat! already did bound check
1786
    @inbounds a[i] = item
92,707,616✔
1787
    return a
92,707,616✔
1788
end
1789

1790
"""
1791
    deleteat!(a::Vector, i::Integer)
1792

1793
Remove the item at the given `i` and return the modified `a`. Subsequent items
1794
are shifted to fill the resulting gap.
1795

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

1798
# Examples
1799
```jldoctest
1800
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1801
5-element Vector{Int64}:
1802
 6
1803
 4
1804
 3
1805
 2
1806
 1
1807
```
1808
"""
1809
function deleteat!(a::Vector, i::Integer)
290✔
1810
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,707✔
1811
    _deleteat!(a, i, 1)
8,703,414✔
1812
    return a
16,710✔
1813
end
1814

1815
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
34,068✔
1816
    if eltype(r) === Bool
75,603✔
1817
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1818
    else
1819
        n = length(a)
75,597✔
1820
        f = first(r)
75,690✔
1821
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
75,597✔
1822
        isempty(r) || _deleteat!(a, f, length(r))
354,786✔
1823
        return a
179,218✔
1824
    end
1825
end
1826

1827
"""
1828
    deleteat!(a::Vector, inds)
1829

1830
Remove the items at the indices given by `inds`, and return the modified `a`.
1831
Subsequent items are shifted to fill the resulting gap.
1832

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

1836
# Examples
1837
```jldoctest
1838
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1839
3-element Vector{Int64}:
1840
 5
1841
 3
1842
 1
1843

1844
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1845
3-element Vector{Int64}:
1846
 5
1847
 3
1848
 1
1849

1850
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1851
ERROR: ArgumentError: indices must be unique and sorted
1852
Stacktrace:
1853
[...]
1854
```
1855
"""
1856
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1857
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
113,011✔
1858

1859
struct Nowhere; end
1860
push!(::Nowhere, _) = nothing
×
1861
_growend!(::Nowhere, _) = nothing
×
1862

1863
function _push_deleted!(dltd, a::Vector, ind)
1864
    @_propagate_inbounds_meta
1,492,136✔
1865
    if isassigned(a, ind)
1,576,482✔
1866
        push!(dltd, a[ind])
1,576,481✔
1867
    else
1868
        _growend!(dltd, 1)
×
1869
    end
1870
end
1871

1872
function _copy_item!(a::Vector, p, q)
1873
    @_propagate_inbounds_meta
4,380,273✔
1874
    if isassigned(a, q)
4,426,478✔
1875
        a[p] = a[q]
4,426,477✔
1876
    else
1877
        _unsetindex!(a, p)
1✔
1878
    end
1879
end
1880

1881
function _deleteat!(a::Vector, inds, dltd=Nowhere())
113,031✔
1882
    n = length(a)
226,061✔
1883
    y = iterate(inds)
113,041✔
1884
    y === nothing && return a
113,031✔
1885
    (p, s) = y
35,492✔
1886
    checkbounds(a, p)
112,820✔
1887
    @inbounds _push_deleted!(dltd, a, p)
112,808✔
1888
    q = p+1
112,808✔
1889
    while true
1,576,482✔
1890
        y = iterate(inds, s)
1,576,493✔
1891
        y === nothing && break
1,576,482✔
1892
        (i,s) = y
1,456,650✔
1893
        if !(q <= i <= n)
1,463,676✔
1894
            if i < q
2✔
1895
                _throw_argerror("indices must be unique and sorted")
1✔
1896
            else
1897
                throw(BoundsError())
1✔
1898
            end
1899
        end
1900
        while q < i
2,888,993✔
1901
            @inbounds _copy_item!(a, p, q)
1,425,319✔
1902
            p += 1; q += 1
1,425,319✔
1903
        end
1,425,319✔
1904
        @inbounds _push_deleted!(dltd, a, i)
1,463,674✔
1905
        q = i+1
1,463,674✔
1906
    end
1,463,674✔
1907
    while q <= n
3,071,771✔
1908
        @inbounds _copy_item!(a, p, q)
2,958,965✔
1909
        p += 1; q += 1
2,958,965✔
1910
    end
2,958,965✔
1911
    _deleteend!(a, n-p+1)
1,576,480✔
1912
    return a
112,806✔
1913
end
1914

1915
# Simpler and more efficient version for logical indexing
1916
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1917
    n = length(a)
4,029✔
1918
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1919
    p = 1
4,024✔
1920
    for (q, i) in enumerate(inds)
8,047✔
1921
        @inbounds _copy_item!(a, p, q)
42,194✔
1922
        p += !i
42,194✔
1923
    end
80,365✔
1924
    _deleteend!(a, n-p+1)
21,353✔
1925
    return a
4,024✔
1926
end
1927

1928
const _default_splice = []
1929

1930
"""
1931
    splice!(a::Vector, index::Integer, [replacement]) -> item
1932

1933
Remove the item at the given index, and return the removed item.
1934
Subsequent items are shifted left to fill the resulting gap.
1935
If specified, replacement values from an ordered
1936
collection will be spliced in place of the removed item.
1937

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

1940
# Examples
1941
```jldoctest
1942
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1943
2
1944

1945
julia> A
1946
5-element Vector{Int64}:
1947
 6
1948
 5
1949
 4
1950
 3
1951
 1
1952

1953
julia> splice!(A, 5, -1)
1954
1
1955

1956
julia> A
1957
5-element Vector{Int64}:
1958
  6
1959
  5
1960
  4
1961
  3
1962
 -1
1963

1964
julia> splice!(A, 1, [-1, -2, -3])
1965
6
1966

1967
julia> A
1968
7-element Vector{Int64}:
1969
 -1
1970
 -2
1971
 -3
1972
  5
1973
  4
1974
  3
1975
 -1
1976
```
1977

1978
To insert `replacement` before an index `n` without removing any items, use
1979
`splice!(collection, n:n-1, replacement)`.
1980
"""
1981
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,695✔
1982
    v = a[i]
3,712✔
1983
    m = length(ins)
3,426✔
1984
    if m == 0
3,426✔
1985
        _deleteat!(a, i, 1)
551✔
1986
    elseif m == 1
2,875✔
1987
        a[i] = only(ins)
267✔
1988
    else
1989
        _growat!(a, i, m-1)
2,608✔
1990
        k = 1
2,608✔
1991
        for x in ins
2,608✔
1992
            a[i+k-1] = x
333,529✔
1993
            k += 1
333,529✔
1994
        end
333,529✔
1995
    end
1996
    return v
3,426✔
1997
end
1998

1999
"""
2000
    splice!(a::Vector, indices, [replacement]) -> items
2001

2002
Remove items at specified indices, and return a collection containing
2003
the removed items.
2004
Subsequent items are shifted left to fill the resulting gaps.
2005
If specified, replacement values from an ordered collection will be spliced in
2006
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
2007

2008
To insert `replacement` before an index `n` without removing any items, use
2009
`splice!(collection, n:n-1, replacement)`.
2010

2011
$(_DOCS_ALIASING_WARNING)
2012

2013
!!! compat "Julia 1.5"
2014
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
2015

2016
!!! compat "Julia 1.8"
2017
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
2018

2019
# Examples
2020
```jldoctest
2021
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
2022
Int64[]
2023

2024
julia> A
2025
8-element Vector{Int64}:
2026
 -1
2027
 -2
2028
 -3
2029
  2
2030
  5
2031
  4
2032
  3
2033
 -1
2034
```
2035
"""
2036
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
22,935,246✔
2037
    v = a[r]
23,005,476✔
2038
    m = length(ins)
71,650✔
2039
    if m == 0
71,650✔
2040
        deleteat!(a, r)
74,059✔
2041
        return v
37,090✔
2042
    end
2043

2044
    n = length(a)
22,864,218✔
2045
    f = first(r)
22,864,218✔
2046
    l = last(r)
22,864,218✔
2047
    d = length(r)
22,864,218✔
2048

2049
    if m < d
22,864,218✔
2050
        delta = d - m
12,627✔
2051
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
19,032✔
2052
    elseif m > d
22,851,591✔
2053
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
22,851,470✔
2054
    end
2055

2056
    k = 1
34,560✔
2057
    for x in ins
22,875,724✔
2058
        a[f+k-1] = x
72,510,364✔
2059
        k += 1
72,510,364✔
2060
    end
96,680,448✔
2061
    return v
22,864,218✔
2062
end
2063

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

2066
function empty!(a::Vector)
4,545,943✔
2067
    _deleteend!(a, length(a))
109,606,904✔
2068
    return a
94,732,435✔
2069
end
2070

2071
# use memcmp for cmp on byte arrays
2072
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
2073
    aref = a.ref
3✔
2074
    bref = b.ref
3✔
2075
    ta = @_gc_preserve_begin aref
3✔
2076
    tb = @_gc_preserve_begin bref
3✔
2077
    pa = unsafe_convert(Ptr{Cvoid}, aref)
3✔
2078
    pb = unsafe_convert(Ptr{Cvoid}, bref)
3✔
2079
    c = memcmp(pa, pb, min(length(a),length(b)))
3✔
2080
    @_gc_preserve_end ta
3✔
2081
    @_gc_preserve_end tb
3✔
2082
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
2083
end
2084

2085
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2086
# use memcmp for == on bit integer types
2087
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,485✔
2088
    if size(a) == size(b)
4,253✔
2089
        aref = a.ref
2,157✔
2090
        bref = b.ref
2,157✔
2091
        ta = @_gc_preserve_begin aref
2,157✔
2092
        tb = @_gc_preserve_begin bref
2,157✔
2093
        pa = unsafe_convert(Ptr{Cvoid}, aref)
2,157✔
2094
        pb = unsafe_convert(Ptr{Cvoid}, bref)
2,157✔
2095
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
2,157✔
2096
        @_gc_preserve_end ta
2,157✔
2097
        @_gc_preserve_end tb
2,157✔
2098
        return c == 0
2,157✔
2099
    else
2100
        return false
×
2101
    end
2102
end
2103

2104
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
5,798✔
2105
    len = length(a)
66,019✔
2106
    if len == length(b)
66,019✔
2107
        aref = a.ref
65,895✔
2108
        bref = b.ref
32,983✔
2109
        ta = @_gc_preserve_begin aref
65,895✔
2110
        tb = @_gc_preserve_begin bref
65,895✔
2111
        T = eltype(Arr)
14,055✔
2112
        pa = unsafe_convert(Ptr{T}, aref)
65,895✔
2113
        pb = unsafe_convert(Ptr{T}, bref)
65,895✔
2114
        c = memcmp(pa, pb, sizeof(T) * len)
65,895✔
2115
        @_gc_preserve_end ta
65,895✔
2116
        @_gc_preserve_end tb
65,895✔
2117
        return c == 0
65,895✔
2118
    else
2119
        return false
124✔
2120
    end
2121
end
2122

2123
"""
2124
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2125

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

2129
# Examples
2130
```jldoctest
2131
julia> A = Vector(1:5)
2132
5-element Vector{Int64}:
2133
 1
2134
 2
2135
 3
2136
 4
2137
 5
2138

2139
julia> reverse(A)
2140
5-element Vector{Int64}:
2141
 5
2142
 4
2143
 3
2144
 2
2145
 1
2146

2147
julia> reverse(A, 1, 4)
2148
5-element Vector{Int64}:
2149
 4
2150
 3
2151
 2
2152
 1
2153
 5
2154

2155
julia> reverse(A, 3, 5)
2156
5-element Vector{Int64}:
2157
 1
2158
 2
2159
 5
2160
 4
2161
 3
2162
```
2163
"""
2164
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
8,552✔
2165
    s, n = Int(start), Int(stop)
949✔
2166
    B = similar(A)
16,831✔
2167
    for i = firstindex(A):s-1
8,553✔
2168
        B[i] = A[i]
1,684✔
2169
    end
3,078✔
2170
    for i = s:n
8,565✔
2171
        B[i] = A[n+s-i]
291,398✔
2172
    end
574,257✔
2173
    for i = n+1:lastindex(A)
16,814✔
2174
        B[i] = A[i]
1,690✔
2175
    end
3,090✔
2176
    return B
8,552✔
2177
end
2178

2179
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2180
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2181
    @eval begin
2182
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
207,798,246✔
2183
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
8,441,858✔
2184
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2185
        function $_f(A::AbstractVector, dim::Integer)
2186
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
2187
            return $_f(A, :)
4✔
2188
        end
2189
    end
2190
end
2191

2192
function reverseind(a::AbstractVector, i::Integer)
3✔
2193
    li = LinearIndices(a)
3✔
2194
    first(li) + last(li) - i
3✔
2195
end
2196

2197
# This implementation of `midpoint` is performance-optimized but safe
2198
# only if `lo <= hi`.
2199
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
53,309,691✔
2200
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2201

2202
"""
2203
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2204

2205
In-place version of [`reverse`](@ref).
2206

2207
# Examples
2208
```jldoctest
2209
julia> A = Vector(1:5)
2210
5-element Vector{Int64}:
2211
 1
2212
 2
2213
 3
2214
 4
2215
 5
2216

2217
julia> reverse!(A);
2218

2219
julia> A
2220
5-element Vector{Int64}:
2221
 5
2222
 4
2223
 3
2224
 2
2225
 1
2226
```
2227
"""
2228
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
134,559,064✔
2229
    s, n = Int(start), Int(stop)
126,088,716✔
2230
    if n > s # non-empty and non-trivial
134,559,061✔
2231
        liv = LinearIndices(v)
35,418,920✔
2232
        if !(first(liv) ≤ s ≤ last(liv))
35,418,920✔
2233
            throw(BoundsError(v, s))
3✔
2234
        elseif !(first(liv) ≤ n ≤ last(liv))
35,418,917✔
2235
            throw(BoundsError(v, n))
1✔
2236
        end
2237
        r = n
119,762✔
2238
        @inbounds for i in s:midpoint(s, n-1)
35,418,916✔
2239
            v[i], v[r] = v[r], v[i]
48,869,734✔
2240
            r -= 1
48,869,734✔
2241
        end
62,320,552✔
2242
    end
2243
    return v
134,559,057✔
2244
end
2245

2246
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2247

2248
vcat() = Vector{Any}()
10,348✔
2249
hcat() = Vector{Any}()
1✔
2250

2251
function hcat(V::Vector{T}...) where T
62✔
2252
    height = length(V[1])
570✔
2253
    for j = 2:length(V)
570✔
2254
        if length(V[j]) != height
636✔
2255
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2256
        end
2257
    end
733✔
2258
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
569✔
2259
end
2260
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2261

2262
function vcat(arrays::Vector{T}...) where T
36,451✔
2263
    n = 0
4,461✔
2264
    for a in arrays
36,451✔
2265
        n += length(a)
2,073,248✔
2266
    end
2,109,693✔
2267
    arr = Vector{T}(undef, n)
72,879✔
2268
    nd = 1
4,461✔
2269
    for a in arrays
36,451✔
2270
        na = length(a)
2,073,248✔
2271
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,073,248✔
2272
        unsafe_copyto!(arr, nd, a, 1, na)
4,141,854✔
2273
        nd += na
2,073,248✔
2274
    end
2,109,693✔
2275
    return arr
36,451✔
2276
end
2277
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
35✔
2278

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

2281
## find ##
2282

2283
"""
2284
    findnext(A, i)
2285

2286
Find the next index after or including `i` of a `true` element of `A`,
2287
or `nothing` if not found.
2288

2289
Indices are of the same type as those returned by [`keys(A)`](@ref)
2290
and [`pairs(A)`](@ref).
2291

2292
# Examples
2293
```jldoctest
2294
julia> A = [false, false, true, false]
2295
4-element Vector{Bool}:
2296
 0
2297
 0
2298
 1
2299
 0
2300

2301
julia> findnext(A, 1)
2302
3
2303

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

2306
julia> A = [false false; true false]
2307
2×2 Matrix{Bool}:
2308
 0  0
2309
 1  0
2310

2311
julia> findnext(A, CartesianIndex(1, 1))
2312
CartesianIndex(2, 1)
2313
```
2314
"""
2315
findnext(A, start) = findnext(identity, A, start)
43,252✔
2316

2317
"""
2318
    findfirst(A)
2319

2320
Return the index or key of the first `true` value in `A`.
2321
Return `nothing` if no such value is found.
2322
To search for other kinds of values, pass a predicate as the first argument.
2323

2324
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2325
and [`pairs(A)`](@ref).
2326

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

2329
# Examples
2330
```jldoctest
2331
julia> A = [false, false, true, false]
2332
4-element Vector{Bool}:
2333
 0
2334
 0
2335
 1
2336
 0
2337

2338
julia> findfirst(A)
2339
3
2340

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

2343
julia> A = [false false; true false]
2344
2×2 Matrix{Bool}:
2345
 0  0
2346
 1  0
2347

2348
julia> findfirst(A)
2349
CartesianIndex(2, 1)
2350
```
2351
"""
2352
findfirst(A) = findfirst(identity, A)
2✔
2353

2354
# Needed for bootstrap, and allows defining only an optimized findnext method
2355
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
11,989✔
2356

2357
"""
2358
    findnext(predicate::Function, A, i)
2359

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

2365
Indices are of the same type as those returned by [`keys(A)`](@ref)
2366
and [`pairs(A)`](@ref).
2367

2368
# Examples
2369
```jldoctest
2370
julia> A = [1, 4, 2, 2];
2371

2372
julia> findnext(isodd, A, 1)
2373
1
2374

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

2377
julia> A = [1 4; 2 2];
2378

2379
julia> findnext(isodd, A, CartesianIndex(1, 1))
2380
CartesianIndex(1, 1)
2381

2382
julia> findnext(isspace, "a b c", 3)
2383
4
2384
```
2385
"""
2386
function findnext(testf::Function, A, start)
19,552✔
2387
    i = oftype(first(keys(A)), start)
45,182✔
2388
    l = last(keys(A))
93,193,606✔
2389
    i > l && return nothing
93,193,606✔
2390
    while true
208,573,042✔
2391
        testf(A[i]) && return i
208,594,159✔
2392
        i == l && break
199,807,324✔
2393
        # nextind(A, l) can throw/overflow
2394
        i = nextind(A, i)
194,497,049✔
2395
    end
194,497,030✔
2396
    return nothing
5,310,270✔
2397
end
2398

2399
"""
2400
    findfirst(predicate::Function, A)
2401

2402
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2403
Return `nothing` if there is no such element.
2404

2405
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2406
and [`pairs(A)`](@ref).
2407

2408
# Examples
2409
```jldoctest
2410
julia> A = [1, 4, 2, 2]
2411
4-element Vector{Int64}:
2412
 1
2413
 4
2414
 2
2415
 2
2416

2417
julia> findfirst(iseven, A)
2418
2
2419

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

2422
julia> findfirst(isequal(4), A)
2423
2
2424

2425
julia> A = [1 4; 2 2]
2426
2×2 Matrix{Int64}:
2427
 1  4
2428
 2  2
2429

2430
julia> findfirst(iseven, A)
2431
CartesianIndex(2, 1)
2432
```
2433
"""
2434
function findfirst(testf::Function, A)
15✔
2435
    for (i, a) in pairs(A)
22✔
2436
        testf(a) && return i
14✔
2437
    end
11✔
2438
    return nothing
8✔
2439
end
2440

2441
# Needed for bootstrap, and allows defining only an optimized findnext method
2442
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
302,643,150✔
2443
    findnext(testf, A, first(keys(A)))
2444

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

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

2451
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2452
    isempty(r) && return nothing
6✔
2453
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2454
    d = convert(S, p.x - first(r))::S
3✔
2455
    iszero(d % step(r)) || return nothing
3✔
2456
    return d ÷ step(r) + 1
3✔
2457
end
2458

2459
"""
2460
    findprev(A, i)
2461

2462
Find the previous index before or including `i` of a `true` element of `A`,
2463
or `nothing` if not found.
2464

2465
Indices are of the same type as those returned by [`keys(A)`](@ref)
2466
and [`pairs(A)`](@ref).
2467

2468
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2469

2470
# Examples
2471
```jldoctest
2472
julia> A = [false, false, true, true]
2473
4-element Vector{Bool}:
2474
 0
2475
 0
2476
 1
2477
 1
2478

2479
julia> findprev(A, 3)
2480
3
2481

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

2484
julia> A = [false false; true true]
2485
2×2 Matrix{Bool}:
2486
 0  0
2487
 1  1
2488

2489
julia> findprev(A, CartesianIndex(2, 1))
2490
CartesianIndex(2, 1)
2491
```
2492
"""
2493
findprev(A, start) = findprev(identity, A, start)
8,326✔
2494

2495
"""
2496
    findlast(A)
2497

2498
Return the index or key of the last `true` value in `A`.
2499
Return `nothing` if there is no `true` value in `A`.
2500

2501
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2502
and [`pairs(A)`](@ref).
2503

2504
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2505

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

2515
julia> findlast(A)
2516
3
2517

2518
julia> A = falses(2,2);
2519

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

2522
julia> A = [true false; true false]
2523
2×2 Matrix{Bool}:
2524
 1  0
2525
 1  0
2526

2527
julia> findlast(A)
2528
CartesianIndex(2, 1)
2529
```
2530
"""
2531
findlast(A) = findlast(identity, A)
23✔
2532

2533
# Needed for bootstrap, and allows defining only an optimized findprev method
2534
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
248✔
2535

2536
"""
2537
    findprev(predicate::Function, A, i)
2538

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

2544
Indices are of the same type as those returned by [`keys(A)`](@ref)
2545
and [`pairs(A)`](@ref).
2546

2547
# Examples
2548
```jldoctest
2549
julia> A = [4, 6, 1, 2]
2550
4-element Vector{Int64}:
2551
 4
2552
 6
2553
 1
2554
 2
2555

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

2558
julia> findprev(isodd, A, 3)
2559
3
2560

2561
julia> A = [4 6; 1 2]
2562
2×2 Matrix{Int64}:
2563
 4  6
2564
 1  2
2565

2566
julia> findprev(isodd, A, CartesianIndex(1, 2))
2567
CartesianIndex(2, 1)
2568

2569
julia> findprev(isspace, "a b c", 3)
2570
2
2571
```
2572
"""
2573
function findprev(testf::Function, A, start)
311✔
2574
    f = first(keys(A))
36,934✔
2575
    i = oftype(f, start)
36,945✔
2576
    i < f && return nothing
38,632✔
2577
    while true
181,523✔
2578
        testf(A[i]) && return i
181,829✔
2579
        i == f && break
143,029✔
2580
        # prevind(A, f) can throw/underflow
2581
        i = prevind(A, i)
142,920✔
2582
    end
142,892✔
2583
    return nothing
106✔
2584
end
2585

2586
"""
2587
    findlast(predicate::Function, A)
2588

2589
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2590
Return `nothing` if there is no such element.
2591

2592
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2593
and [`pairs(A)`](@ref).
2594

2595
# Examples
2596
```jldoctest
2597
julia> A = [1, 2, 3, 4]
2598
4-element Vector{Int64}:
2599
 1
2600
 2
2601
 3
2602
 4
2603

2604
julia> findlast(isodd, A)
2605
3
2606

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

2609
julia> A = [1 2; 3 4]
2610
2×2 Matrix{Int64}:
2611
 1  2
2612
 3  4
2613

2614
julia> findlast(isodd, A)
2615
CartesianIndex(2, 1)
2616
```
2617
"""
2618
function findlast(testf::Function, A)
3✔
2619
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2620
        testf(a) && return i
6✔
2621
    end
6✔
2622
    return nothing
2✔
2623
end
2624

2625
# Needed for bootstrap, and allows defining only an optimized findprev method
2626
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
15,069✔
2627
    findprev(testf, A, last(keys(A)))
2628

2629
"""
2630
    findall(f::Function, A)
2631

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

2635
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2636
and [`pairs(A)`](@ref).
2637

2638
# Examples
2639
```jldoctest
2640
julia> x = [1, 3, 4]
2641
3-element Vector{Int64}:
2642
 1
2643
 3
2644
 4
2645

2646
julia> findall(isodd, x)
2647
2-element Vector{Int64}:
2648
 1
2649
 2
2650

2651
julia> A = [1 2 0; 3 4 0]
2652
2×3 Matrix{Int64}:
2653
 1  2  0
2654
 3  4  0
2655
julia> findall(isodd, A)
2656
2-element Vector{CartesianIndex{2}}:
2657
 CartesianIndex(1, 1)
2658
 CartesianIndex(2, 1)
2659

2660
julia> findall(!iszero, A)
2661
4-element Vector{CartesianIndex{2}}:
2662
 CartesianIndex(1, 1)
2663
 CartesianIndex(2, 1)
2664
 CartesianIndex(1, 2)
2665
 CartesianIndex(2, 2)
2666

2667
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2668
Dict{Symbol, Int64} with 3 entries:
2669
  :A => 10
2670
  :B => -1
2671
  :C => 0
2672

2673
julia> findall(≥(0), d)
2674
2-element Vector{Symbol}:
2675
 :A
2676
 :C
2677

2678
```
2679
"""
2680
function findall(testf::Function, A)
24✔
2681
    gen = (first(p) for p in pairs(A) if testf(last(p)))
39✔
2682
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
39✔
2683
end
2684

2685
# Broadcasting is much faster for small testf, and computing
2686
# integer indices from logical index using findall has a negligible cost
2687
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
267✔
2688

2689
"""
2690
    findall(A)
2691

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

2696
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2697
and [`pairs(A)`](@ref).
2698

2699
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2700

2701
# Examples
2702
```jldoctest
2703
julia> A = [true, false, false, true]
2704
4-element Vector{Bool}:
2705
 1
2706
 0
2707
 0
2708
 1
2709

2710
julia> findall(A)
2711
2-element Vector{Int64}:
2712
 1
2713
 4
2714

2715
julia> A = [true false; false true]
2716
2×2 Matrix{Bool}:
2717
 1  0
2718
 0  1
2719

2720
julia> findall(A)
2721
2-element Vector{CartesianIndex{2}}:
2722
 CartesianIndex(1, 1)
2723
 CartesianIndex(2, 2)
2724

2725
julia> findall(falses(3))
2726
Int64[]
2727
```
2728
"""
2729
function findall(A)
4✔
2730
    collect(first(p) for p in pairs(A) if last(p))
4✔
2731
end
2732

2733
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2734
function findall(A::AbstractArray{Bool})
823✔
2735
    n = count(A)
3,670✔
2736
    I = Vector{eltype(keys(A))}(undef, n)
6,958✔
2737
    cnt = 1
3,665✔
2738
    for (i,a) in pairs(A)
7,322✔
2739
        if a
207,518✔
2740
            I[cnt] = i
128,944✔
2741
            cnt += 1
128,944✔
2742
        end
2743
    end
411,376✔
2744
    I
3,665✔
2745
end
2746

2747
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2748
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2749
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2750

2751
# similar to Matlab's ismember
2752
"""
2753
    indexin(a, b)
2754

2755
Return an array containing the first index in `b` for
2756
each value in `a` that is a member of `b`. The output
2757
array contains `nothing` wherever `a` is not a member of `b`.
2758

2759
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2760

2761
# Examples
2762
```jldoctest
2763
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2764

2765
julia> b = ['a', 'b', 'c'];
2766

2767
julia> indexin(a, b)
2768
6-element Vector{Union{Nothing, Int64}}:
2769
 1
2770
 2
2771
 3
2772
 2
2773
  nothing
2774
 1
2775

2776
julia> indexin(b, a)
2777
3-element Vector{Union{Nothing, Int64}}:
2778
 1
2779
 2
2780
 3
2781
```
2782
"""
2783
function indexin(a, b::AbstractArray)
7✔
2784
    inds = keys(b)
7✔
2785
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2786
    for (val, ind) in zip(b, inds)
14✔
2787
        get!(bdict, val, ind)
30✔
2788
    end
53✔
2789
    return Union{eltype(inds), Nothing}[
7✔
2790
        get(bdict, i, nothing) for i in a
2791
    ]
2792
end
2793

2794
function _findin(a::Union{AbstractArray, Tuple}, b)
375✔
2795
    ind  = Vector{eltype(keys(a))}()
561✔
2796
    bset = Set(b)
377✔
2797
    @inbounds for (i,ai) in pairs(a)
606✔
2798
        ai in bset && push!(ind, i)
90,559✔
2799
    end
180,565✔
2800
    ind
375✔
2801
end
2802

2803
# If two collections are already sorted, _findin can be computed with
2804
# a single traversal of the two collections. This is much faster than
2805
# using a hash table (although it has the same complexity).
2806
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
9✔
2807
    viter, witer = keys(v), eachindex(w)
9✔
2808
    out  = eltype(viter)[]
9✔
2809
    vy, wy = iterate(viter), iterate(witer)
11✔
2810
    if vy === nothing || wy === nothing
17✔
2811
        return out
2✔
2812
    end
2813
    viteri, i = vy
7✔
2814
    witerj, j = wy
7✔
2815
    @inbounds begin
7✔
2816
        vi, wj = v[viteri], w[witerj]
7✔
2817
        while true
54✔
2818
            if isless(vi, wj)
56✔
2819
                vy = iterate(viter, i)
25✔
2820
                if vy === nothing
14✔
2821
                    break
2✔
2822
                end
2823
                viteri, i = vy
12✔
2824
                vi        = v[viteri]
12✔
2825
            elseif isless(wj, vi)
40✔
2826
                wy = iterate(witer, j)
44✔
2827
                if wy === nothing
24✔
2828
                    break
4✔
2829
                end
2830
                witerj, j = wy
20✔
2831
                wj        = w[witerj]
20✔
2832
            else
2833
                push!(out, viteri)
16✔
2834
                vy = iterate(viter, i)
25✔
2835
                if vy === nothing
16✔
2836
                    break
1✔
2837
                end
2838
                # We only increment the v iterator because v can have
2839
                # repeated matches to a single value in w
2840
                viteri, i = vy
15✔
2841
                vi        = v[viteri]
15✔
2842
            end
2843
        end
47✔
2844
    end
2845
    return out
7✔
2846
end
2847

2848
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2849
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2850
        return _sortedfindin(x, pred.x)
9✔
2851
    else
2852
        return _findin(x, pred.x)
6✔
2853
    end
2854
end
2855
# issorted fails for some element types so the method above has to be restricted
2856
# to element with isless/< defined.
2857
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
373✔
2858
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2859

2860
# Copying subregions
2861
function indcopy(sz::Dims, I::Vector)
1✔
2862
    n = length(I)
1✔
2863
    s = sz[n]
1✔
2864
    for i = n+1:length(sz)
2✔
2865
        s *= sz[i]
×
2866
    end
×
2867
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2868
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2869
    dst, src
1✔
2870
end
2871

2872
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2873
    n = length(I)
1✔
2874
    s = sz[n]
1✔
2875
    for i = n+1:length(sz)
1✔
2876
        s *= sz[i]
×
2877
    end
×
2878
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2879
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2880
    dst, src
1✔
2881
end
2882

2883
## Filter ##
2884

2885
"""
2886
    filter(f, a)
2887

2888
Return a copy of collection `a`, removing elements for which `f` is `false`.
2889
The function `f` is passed one argument.
2890

2891
!!! compat "Julia 1.4"
2892
    Support for `a` as a tuple requires at least Julia 1.4.
2893

2894
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2895

2896
# Examples
2897
```jldoctest
2898
julia> a = 1:10
2899
1:10
2900

2901
julia> filter(isodd, a)
2902
5-element Vector{Int64}:
2903
 1
2904
 3
2905
 5
2906
 7
2907
 9
2908
```
2909
"""
2910
function filter(f, a::Array{T, N}) where {T, N}
18,730✔
2911
    j = 1
16,189✔
2912
    b = Vector{T}(undef, length(a))
37,340✔
2913
    for ai in a
18,730✔
2914
        @inbounds b[j] = ai
3,263,492✔
2915
        j = ifelse(f(ai)::Bool, j+1, j)
3,264,684✔
2916
    end
3,263,492✔
2917
    resize!(b, j-1)
18,730✔
2918
    sizehint!(b, length(b))
18,730✔
2919
    b
16,189✔
2920
end
2921

2922
function filter(f, a::AbstractArray)
457✔
2923
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
457✔
2924

2925
    j = 1
457✔
2926
    idxs = Vector{Int}(undef, length(a))
752✔
2927
    for idx in eachindex(a)
460✔
2928
        @inbounds idxs[j] = idx
103,549✔
2929
        ai = @inbounds a[idx]
103,549✔
2930
        j = ifelse(f(ai)::Bool, j+1, j)
105,082✔
2931
    end
206,802✔
2932
    resize!(idxs, j-1)
456✔
2933
    res = a[idxs]
456✔
2934
    empty!(idxs)
4,200✔
2935
    sizehint!(idxs, 0)
456✔
2936
    return res
456✔
2937
end
2938

2939
"""
2940
    filter!(f, a)
2941

2942
Update collection `a`, removing elements for which `f` is `false`.
2943
The function `f` is passed one argument.
2944

2945
# Examples
2946
```jldoctest
2947
julia> filter!(isodd, Vector(1:10))
2948
5-element Vector{Int64}:
2949
 1
2950
 3
2951
 5
2952
 7
2953
 9
2954
```
2955
"""
2956
function filter!(f, a::AbstractVector)
919,928✔
2957
    j = firstindex(a)
1,156✔
2958
    for ai in a
131,493,620✔
2959
        @inbounds a[j] = ai
151,527,967✔
2960
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
153,382,827✔
2961
    end
151,527,976✔
2962
    j > lastindex(a) && return a
131,493,619✔
2963
    if a isa Vector
415✔
2964
        resize!(a, j-1)
74,877✔
2965
        sizehint!(a, j-1)
74,877✔
2966
    else
2967
        deleteat!(a, j:lastindex(a))
1✔
2968
    end
2969
    return a
74,878✔
2970
end
2971

2972
"""
2973
    filter(f)
2974

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

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

2981
# Examples
2982
```jldoctest
2983
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2984
(1, 2, 4, 6)
2985

2986
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2987
3-element Vector{Vector{Int64}}:
2988
 [2]
2989
 [2, 4]
2990
 [4]
2991
```
2992
!!! compat "Julia 1.9"
2993
    This method requires at least Julia 1.9.
2994
"""
2995
function filter(f)
1✔
2996
    Fix1(filter, f)
1✔
2997
end
2998

2999
"""
3000
    keepat!(a::Vector, inds)
3001
    keepat!(a::BitVector, inds)
3002

3003
Remove the items at all the indices which are not given by `inds`,
3004
and return the modified `a`.
3005
Items which are kept are shifted to fill the resulting gaps.
3006

3007
$(_DOCS_ALIASING_WARNING)
3008

3009
`inds` must be an iterator of sorted and unique integer indices.
3010
See also [`deleteat!`](@ref).
3011

3012
!!! compat "Julia 1.7"
3013
    This function is available as of Julia 1.7.
3014

3015
# Examples
3016
```jldoctest
3017
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
3018
3-element Vector{Int64}:
3019
 6
3020
 4
3021
 2
3022
```
3023
"""
3024
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
3025

3026
"""
3027
    keepat!(a::Vector, m::AbstractVector{Bool})
3028
    keepat!(a::BitVector, m::AbstractVector{Bool})
3029

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

3034
# Examples
3035
```jldoctest
3036
julia> a = [:a, :b, :c];
3037

3038
julia> keepat!(a, [true, false, true])
3039
2-element Vector{Symbol}:
3040
 :a
3041
 :c
3042

3043
julia> a
3044
2-element Vector{Symbol}:
3045
 :a
3046
 :c
3047
```
3048
"""
3049
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
3050

3051
# set-like operators for vectors
3052
# These are moderately efficient, preserve order, and remove dupes.
3053

3054
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
409,735✔
3055
    # P, U force specialization
3056
    if pred(x, state)
806,384✔
3057
        update!(state, x)
19,280✔
3058
        true
3059
    else
3060
        false
3061
    end
3062
end
3063

3064
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
293✔
3065
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
4,304✔
3066

3067
function _grow!(pred!, v::AbstractVector, itrs)
111✔
3068
    filter!(pred!, v) # uniquify v
320✔
3069
    for itr in itrs
320✔
3070
        mapfilter(pred!, push!, itr, v)
627✔
3071
    end
927✔
3072
    return v
320✔
3073
end
3074

3075
union!(v::AbstractVector{T}, itrs...) where {T} =
288✔
3076
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3077

3078
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
3079
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3080

3081
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
2✔
3082
    seen = Set{eltype(v)}()
6✔
3083
    filter!(_grow_filter!(seen), v)
6✔
3084
    shrinker!(seen, itrs...)
6✔
3085
    filter!(in(seen), v)
6✔
3086
end
3087

3088
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
3089
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
3090

3091
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
4,272✔
3092

3093
function _shrink(shrinker!::F, itr, itrs) where F
4,175✔
3094
    T = promote_eltype(itr, itrs...)
4,120✔
3095
    keep = shrinker!(Set{T}(itr), itrs...)
5,235✔
3096
    vectorfilter(T, _shrink_filter!(keep), itr)
4,213✔
3097
end
3098

3099
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
465✔
3100
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
3,748✔
3101

3102
function intersect(v::AbstractVector, r::AbstractRange)
7✔
3103
    T = promote_eltype(v, r)
11✔
3104
    common = Iterators.filter(in(r), v)
59✔
3105
    seen = Set{T}(common)
59✔
3106
    return vectorfilter(T, _shrink_filter!(seen), common)
59✔
3107
end
3108
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
3109

3110
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3111
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
3,852✔
3112
    if i isa Bool # Not via dispatch to avoid ambiguities
29,665,452✔
3113
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3114
    else
3115
        _getindex(v, i)
591,863,668✔
3116
    end
3117
end
3118

3119
"""
3120
    wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
3121

3122
Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version
3123
of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers.
3124
"""
3125
function wrap end
3126

3127
# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller
3128
function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N}
212✔
3129
    mem = ref.mem
5,795,712✔
3130
    mem_len = length(mem) + 1 - memoryrefoffset(ref)
5,795,712✔
3131
    len = Core.checked_dims(dims...)
222✔
3132
    @boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len)
5,795,715✔
3133
    if N != 1 && !(ref === GenericMemoryRef(mem) && len === mem_len)
9✔
3134
        mem = ccall(:jl_genericmemory_slice, Memory{T}, (Any, Ptr{Cvoid}, Int), mem, ref.ptr_or_offset, len)
3✔
3135
        ref = memoryref(mem)
3✔
3136
    end
3137
    return ref
5,795,709✔
3138
end
3139

3140
@noinline invalid_wrap_err(len, dims, proddims) = throw(DimensionMismatch(LazyString(
3✔
3141
    "Attempted to wrap a MemoryRef of length ", len, " with an Array of size dims=", dims,
3142
    " which is invalid because prod(dims) = ", proddims, " > ", len,
3143
    " so that the array would have more elements than the underlying memory can store.")))
3144

3145
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
4✔
3146
    dims = convert(Dims, dims)
4✔
3147
    ref = _wrap(m, dims)
4✔
3148
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
4✔
3149
end
3150

3151
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
3✔
3152
    dims = convert(Dims, dims)
3✔
3153
    ref = _wrap(memoryref(m), dims)
4✔
3154
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
2✔
3155
end
3156
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
4✔
3157
    dims = (Int(l),)
5,795,494✔
3158
    ref = _wrap(m, dims)
5,795,496✔
3159
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
748,980✔
3160
end
3161
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
1✔
3162
    dims = (Int(l),)
1✔
3163
    ref = _wrap(memoryref(m), (l,))
1✔
3164
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
1✔
3165
end
3166
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
3167
    ref = memoryref(m)
1,588,147✔
3168
    dims = (length(m),)
1,588,147✔
3169
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
1,557,523✔
3170
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