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

JuliaLang / julia / #37938

20 Oct 2024 01:04AM UTC coverage: 87.645% (-0.02%) from 87.661%
#37938

push

local

web-flow
Few more tests for AbstractChar (#56249)

79145 of 90302 relevant lines covered (87.64%)

17047965.14 hits per line

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

94.83
/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,926✔
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}()
666,716✔
159
function vect(X::T...) where T
50,753✔
160
    @_terminates_locally_meta
103,434✔
161
    vec = Vector{T}(undef, length(X))
1,757,142✔
162
    @_safeindex for i = 1:length(X)
240,501✔
163
        vec[i] = X[i]
4,869,228✔
164
    end
6,512,143✔
165
    return vec
189,143✔
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,752✔
184
    T = promote_typeof(X...)
55,762✔
185
    return T[X...]
55,955✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
4,980✔
190
    d < 1 && error("arraysize: dimension out of range")
65,397,164✔
191
    sz = getfield(a, :size)
65,518,138✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
89,717,635✔
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,302✔
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,302✔
215

216
function _unsetindex!(A::Array, i::Int)
217
    @inline
10,999,556✔
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,926✔
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,228✔
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,101,540✔
247
    @_noub_if_noinbounds_meta
6,101,540✔
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))
27,372,490✔
269
    return dest
26,391,390✔
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,550,823✔
284
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
17,141,242✔
285
    return dest
8,570,624✔
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,509✔
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,120,962✔
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)
292,306,749✔
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
181,532,904✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
141,383,933✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
141,383,952✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
141,383,913✔
306
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
141,383,918✔
307
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
282,767,776✔
309
    end
310
    return dest
141,383,666✔
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,321✔
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))
44,242,584✔
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
268,523✔
328
    x = x isa T ? x : convert(T, x)::T
268,524✔
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)
1,007,026,131✔
333
        @inbounds dest[i] = x
2,147,483,647✔
334
    end
2,147,483,647✔
335
    return dest
1,007,026,131✔
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}
160,724✔
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
282,713✔
353
    ref = a.ref
208,331,382✔
354
    newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a))
208,331,384✔
355
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
208,331,383✔
356
end
357

358
# a mutating version of copyto! that results in dst aliasing src afterwards
359
function _take!(dst::Array{T,N}, src::Array{T,N}) where {T,N}
360
    if getfield(dst, :ref) !== getfield(src, :ref)
575✔
361
        setfield!(dst, :ref, getfield(src, :ref))
15✔
362
    end
363
    if getfield(dst, :size) !== getfield(src, :size)
575✔
364
        setfield!(dst, :size, getfield(src, :size))
360✔
365
    end
366
    return dst
575✔
367
end
368

369
## Constructors ##
370

371
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
241,206✔
372
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
4,063✔
373
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
16,278✔
374
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
27,112✔
375
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
4,558,770✔
376
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
120,787,737✔
377
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
643✔
378

379
# T[x...] constructs Array{T,1}
380
"""
381
    getindex(type[, elements...])
382

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

386
# Examples
387
```jldoctest
388
julia> Int8[1, 2, 3]
389
3-element Vector{Int8}:
390
 1
391
 2
392
 3
393

394
julia> getindex(Int8, 1, 2, 3)
395
3-element Vector{Int8}:
396
 1
397
 2
398
 3
399
```
400
"""
401
function getindex(::Type{T}, vals...) where T
246,019✔
402
    @inline
189,729✔
403
    @_effect_free_terminates_locally_meta
189,729✔
404
    a = Vector{T}(undef, length(vals))
1,114,005,962✔
405
    if vals isa NTuple
189,761✔
406
        @_safeindex for i in 1:length(vals)
695,473✔
407
            a[i] = vals[i]
82,238,694✔
408
        end
1,177,189✔
409
    else
410
        # use afoldl to avoid type instability inside loop
411
        afoldl(1, vals...) do i, v
58,992✔
412
            @inbounds a[i] = v
123,971✔
413
            return i + 1
123,971✔
414
        end
415
    end
416
    return a
379,824✔
417
end
418

419
function getindex(::Type{Any}, @nospecialize vals...)
26,975,508✔
420
    @_effect_free_terminates_locally_meta
10,491✔
421
    a = Vector{Any}(undef, length(vals))
103,228,909✔
422
    @_safeindex for i = 1:length(vals)
34,717,861✔
423
        a[i] = vals[i]
138,478,537✔
424
    end
135,730,743✔
425
    return a
27,142,190✔
426
end
427
getindex(::Type{Any}) = Vector{Any}()
97,951,757✔
428

429
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
5✔
430
    ref = a.ref
204,329✔
431
    t = @_gc_preserve_begin ref
204,329✔
432
    p = unsafe_convert(Ptr{Cvoid}, ref)
204,329✔
433
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
204,332✔
434
    @_gc_preserve_end t
204,326✔
435
    return a
10,491✔
436
end
437

438
to_dim(d::Integer) = d
×
439
to_dim(d::OneTo) = last(d)
212✔
440

441
"""
442
    fill(value, dims::Tuple)
443
    fill(value, dims...)
444

445
Create an array of size `dims` with every location set to `value`.
446

447
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
448
with `1.0` in every location of the array.
449

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

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

463
```jldoctest
464
julia> v = fill([], 3)
465
3-element Vector{Vector{Any}}:
466
 []
467
 []
468
 []
469

470
julia> v[1] === v[2] === v[3]
471
true
472

473
julia> value = v[1]
474
Any[]
475

476
julia> push!(value, 867_5309)
477
1-element Vector{Any}:
478
 8675309
479

480
julia> v
481
3-element Vector{Vector{Any}}:
482
 [8675309]
483
 [8675309]
484
 [8675309]
485
```
486

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

490
```jldoctest
491
julia> v2 = [[] for _ in 1:3]
492
3-element Vector{Vector{Any}}:
493
 []
494
 []
495
 []
496

497
julia> v2[1] === v2[2] === v2[3]
498
false
499

500
julia> push!(v2[1], 8675309)
501
1-element Vector{Any}:
502
 8675309
503

504
julia> v2
505
3-element Vector{Vector{Any}}:
506
 [8675309]
507
 []
508
 []
509
```
510

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

513
# Examples
514
```jldoctest
515
julia> fill(1.0, (2,3))
516
2×3 Matrix{Float64}:
517
 1.0  1.0  1.0
518
 1.0  1.0  1.0
519

520
julia> fill(42)
521
0-dimensional Array{Int64, 0}:
522
42
523

524
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
525
2-element Vector{Vector{Float64}}:
526
 [0.0, 0.0]
527
 [0.0, 0.0]
528

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

531
julia> A # both A[1] and A[2] are the very same vector
532
2-element Vector{Vector{Float64}}:
533
 [42.0, 0.0]
534
 [42.0, 0.0]
535
```
536
"""
537
function fill end
538

539
fill(v, dims::DimOrInd...) = fill(v, dims)
2,147,483,647✔
540
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
541
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
2,147,483,647✔
542
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
×
543
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
137✔
544

545
"""
546
    zeros([T=Float64,] dims::Tuple)
547
    zeros([T=Float64,] dims...)
548

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

552
# Examples
553
```jldoctest
554
julia> zeros(1)
555
1-element Vector{Float64}:
556
 0.0
557

558
julia> zeros(Int8, 2, 3)
559
2×3 Matrix{Int8}:
560
 0  0  0
561
 0  0  0
562
```
563
"""
564
function zeros end
565

566
"""
567
    ones([T=Float64,] dims::Tuple)
568
    ones([T=Float64,] dims...)
569

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

573
# Examples
574
```jldoctest
575
julia> ones(1,2)
576
1×2 Matrix{Float64}:
577
 1.0  1.0
578

579
julia> ones(ComplexF64, 2, 3)
580
2×3 Matrix{ComplexF64}:
581
 1.0+0.0im  1.0+0.0im  1.0+0.0im
582
 1.0+0.0im  1.0+0.0im  1.0+0.0im
583
```
584
"""
585
function ones end
586

587
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
588
    @eval begin
589
        $fname(dims::DimOrInd...) = $fname(dims)
20,452,788✔
590
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
2,147,483,647✔
591
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,458,430✔
592
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,264✔
593
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
12,436✔
594
            a = Array{T,N}(undef, dims)
182,642,961✔
595
            fill!(a, $felt(T))
2,147,483,647✔
596
            return a
131,843,609✔
597
        end
598
        function $fname(::Type{T}, dims::Tuple{}) where {T}
599
            a = Array{T}(undef)
20✔
600
            fill!(a, $felt(T))
20✔
601
            return a
20✔
602
        end
603
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
66✔
604
            a = similar(Array{T,N}, dims)
66✔
605
            fill!(a, $felt(T))
132✔
606
            return a
66✔
607
        end
608
    end
609
end
610

611
## Conversions ##
612

613
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
292,445✔
614

615
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✔
616

617
## Constructors ##
618

619
if nameof(@__MODULE__) === :Base  # avoid method overwrite
620
# constructors should make copies
621
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
305,375✔
622
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
9,914✔
623
end
624

625
## copying iterators to containers
626

627
"""
628
    collect(element_type, collection)
629

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

633
# Examples
634
```jldoctest
635
julia> collect(Float64, 1:2:5)
636
3-element Vector{Float64}:
637
 1.0
638
 3.0
639
 5.0
640
```
641
"""
642
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
31,095,802✔
643

644
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
41,699✔
645
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
646
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
31,054,094✔
647
    a = Vector{T}()
31,054,103✔
648
    for x in itr
53,476,674✔
649
        push!(a, x)
150,382,489✔
650
    end
278,342,406✔
651
    return a
31,054,103✔
652
end
653

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

657
_similar_shape(itr, ::SizeUnknown) = nothing
×
658
_similar_shape(itr, ::HasLength) = length(itr)::Integer
52,359,593✔
659
_similar_shape(itr, ::HasShape) = axes(itr)
449,754,910✔
660

661
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,351,683✔
662
    similar(c, T, 0)
663
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
7,526,134✔
664
    similar(c, T, len)
665
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
300,192✔
666
    similar(c, T, axs)
667

668
# make a collection appropriate for collecting `itr::Generator`
669
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
259✔
670
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
73,508,336✔
671
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
1,245,080,533✔
672

673
# used by syntax lowering for simple typed comprehensions
674
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
1,316,924,513✔
675

676

677
"""
678
    collect(iterator)
679

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

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

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

692
# Examples
693

694
Collect items from a `UnitRange{Int64}` collection:
695

696
```jldoctest
697
julia> collect(1:3)
698
3-element Vector{Int64}:
699
 1
700
 2
701
 3
702
```
703

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

706
```jldoctest
707
julia> collect(x^2 for x in 1:3)
708
3-element Vector{Int64}:
709
 1
710
 4
711
 9
712
```
713

714
Collecting an empty iterator where the result type depends on type inference:
715

716
```jldoctest
717
julia> [rand(Bool) ? 1 : missing for _ in []]
718
Union{Missing, Int64}[]
719
```
720

721
When the iterator is non-empty, the result type depends only on values:
722

723
```julia-repl
724
julia> [rand(Bool) ? 1 : missing for _ in [""]]
725
1-element Vector{Int64}:
726
 1
727
```
728
"""
729
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
9,109,696✔
730

731
collect(A::AbstractArray) = _collect_indices(axes(A), A)
129,813✔
732

733
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
191,635✔
734

735
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
7,512,599✔
736
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
737

738
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,351,613✔
739
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,351,645✔
740
    for x in itr
2,701,222✔
741
        push!(a,x)
10,479,840✔
742
    end
17,965,755✔
743
    return a
1,351,644✔
744
end
745

746
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
747
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
131,189✔
748
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
749
function _collect_indices(indsA, A)
36✔
750
    B = Array{eltype(A)}(undef, length.(indsA))
237✔
751
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
752
end
753

754
# NOTE: this function is not meant to be called, only inferred, for the
755
# purpose of bounding the types of values generated by an iterator.
756
function _iterator_upper_bound(itr)
×
757
    x = iterate(itr)
×
758
    while x !== nothing
×
759
        val = getfield(x, 1)
×
760
        if inferencebarrier(nothing)
×
761
            return val
×
762
        end
763
        x = iterate(itr, getfield(x, 2))
×
764
    end
×
765
    throw(nothing)
×
766
end
767

768
# define this as a macro so that the call to Core.Compiler
769
# gets inlined into the caller before recursion detection
770
# gets a chance to see it, so that recursive calls to the caller
771
# don't trigger the inference limiter
772
if isdefined(Core, :Compiler)
773
    macro default_eltype(itr)
774
        I = esc(itr)
775
        return quote
776
            if $I isa Generator && ($I).f isa Type
544,437✔
777
                T = ($I).f
12,745✔
778
            else
779
                T = Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)})
531,692✔
780
            end
781
            promote_typejoin_union(T)
544,441✔
782
        end
783
    end
784
else
785
    macro default_eltype(itr)
786
        I = esc(itr)
787
        return quote
788
            if $I isa Generator && ($I).f isa Type
789
                promote_typejoin_union($I.f)
790
            else
791
                Any
792
            end
793
        end
794
    end
795
end
796

797
function collect(itr::Generator)
543,941✔
798
    isz = IteratorSize(itr.iter)
394,119✔
799
    et = @default_eltype(itr)
800
    if isa(isz, SizeUnknown)
394,119✔
801
        return grow_to!(Vector{et}(), itr)
100,577✔
802
    else
803
        shp = _similar_shape(itr, isz)
824,319✔
804
        y = iterate(itr)
1,636,056✔
805
        if y === nothing
823,693✔
806
            return _array_for(et, isz, shp)
952✔
807
        end
808
        v1, st = y
392,171✔
809
        dest = _array_for(typeof(v1), isz, shp)
1,633,966✔
810
        # The typeassert gives inference a helping hand on the element type and dimensionality
811
        # (work-around for #28382)
812
        et′ = et <: Type ? Type : et
392,171✔
813
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
392,323✔
814
        collect_to_with_first!(dest, v1, itr, st)::RT
10,812,745✔
815
    end
816
end
817

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

821
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
191,656✔
822
    et = @default_eltype(itr)
127,817✔
823
    shp = _similar_shape(itr, isz)
191,663✔
824
    y = iterate(itr)
381,887✔
825
    if y === nothing
191,661✔
826
        return _similar_for(c, et, itr, isz, shp)
1,412✔
827
    end
828
    v1, st = y
126,670✔
829
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
297,155✔
830
    # The typeassert gives inference a helping hand on the element type and dimensionality
831
    # (work-around for #28382)
832
    et′ = et <: Type ? Type : et
126,648✔
833
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
126,663✔
834
    collect_to_with_first!(dest, v1, itr, st)::RT
190,249✔
835
end
836

837
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
85,875✔
838
    i1 = first(LinearIndices(dest))
518,821✔
839
    dest[i1] = v1
1,012,990✔
840
    return collect_to!(dest, itr, i1+1, st)
11,660,569✔
841
end
842

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

848
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
210✔
849
    @inline
340✔
850
    new = similar(dest, promote_typejoin(T, typeof(el)))
768✔
851
    f = first(LinearIndices(dest))
340✔
852
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
765✔
853
    @inbounds new[i] = el
385✔
854
    return new
385✔
855
end
856

857
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
129,189✔
858
    # collect to dest array, checking the type of each result. if a result does not
859
    # match, widen the result type and re-dispatch.
860
    i = offs
519,161✔
861
    while true
92,493,589✔
862
        y = iterate(itr, st)
183,974,158✔
863
        y === nothing && break
92,493,579✔
864
        el, st = y
90,505,699✔
865
        if el isa T
90,526,985✔
866
            @inbounds dest[i] = el
91,480,214✔
867
            i += 1
91,480,214✔
868
        else
869
            new = setindex_widen_up_to(dest, el, i)
385✔
870
            return collect_to!(new, itr, i+1, st)
385✔
871
        end
872
    end
91,480,214✔
873
    return dest
1,012,980✔
874
end
875

876
function grow_to!(dest, itr)
1,187✔
877
    y = iterate(itr)
1,491✔
878
    y === nothing && return dest
1,225✔
879
    dest2 = empty(dest, typeof(y[1]))
279✔
880
    push!(dest2, y[1])
325✔
881
    grow_to!(dest2, itr, y[2])
272✔
882
end
883

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

897
function grow_to!(dest, itr, st)
267✔
898
    T = eltype(dest)
165✔
899
    y = iterate(itr, st)
470✔
900
    while y !== nothing
3,938✔
901
        el, st = y
2,324✔
902
        if el isa T
2,324✔
903
            push!(dest, el)
3,659✔
904
        else
905
            new = push_widen(dest, el)
13✔
906
            return grow_to!(new, itr, st)
10✔
907
        end
908
        y = iterate(itr, st)
5,685✔
909
    end
3,656✔
910
    return dest
272✔
911
end
912

913
## Iteration ##
914

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

917
## Indexing: getindex ##
918

919
"""
920
    getindex(collection, key...)
921

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

925
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
926

927
# Examples
928
```jldoctest
929
julia> A = Dict("a" => 1, "b" => 2)
930
Dict{String, Int64} with 2 entries:
931
  "b" => 2
932
  "a" => 1
933

934
julia> getindex(A, "a")
935
1
936
```
937
"""
938
function getindex end
939

940
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
120,847✔
941
    @inline
199,844,205✔
942
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
212,384,341✔
943
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
212,384,709✔
944
end
945

946
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
947
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
9,575,851✔
948
    @inline
869,466✔
949
    @boundscheck checkbounds(A, I)
76,159,536✔
950
    lI = length(I)
76,159,545✔
951
    X = similar(A, axes(I))
119,735,302✔
952
    if lI > 0
76,159,534✔
953
        copyto!(X, firstindex(X), A, first(I), lI)
87,151,524✔
954
    end
955
    return X
76,159,534✔
956
end
957

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

961
function getindex(A::Array, c::Colon)
4,450✔
962
    lI = length(A)
2,276,963✔
963
    X = similar(A, lI)
4,553,924✔
964
    if lI > 0
2,276,963✔
965
        unsafe_copyto!(X, 1, A, 1, lI)
4,553,922✔
966
    end
967
    return X
2,276,963✔
968
end
969

970
# This is redundant with the abstract fallbacks, but needed for bootstrap
971
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
141✔
972
    return S[ A[i] for i in I ]
13,029,441✔
973
end
974

975
## Indexing: setindex! ##
976

977
"""
978
    setindex!(collection, value, key...)
979

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

983
# Examples
984
```jldoctest
985
julia> a = Dict("a"=>1)
986
Dict{String, Int64} with 1 entry:
987
  "a" => 1
988

989
julia> setindex!(a, 2, "b")
990
Dict{String, Int64} with 2 entries:
991
  "b" => 2
992
  "a" => 1
993
```
994
"""
995
function setindex! end
996

997
function setindex!(A::Array{T}, x, i::Int) where {T}
21,501,417✔
998
    @_propagate_inbounds_meta
722,456,958✔
999
    x = x isa T ? x : convert(T, x)::T
1,819,108,459✔
1000
    return _setindex!(A, x, i)
2,147,483,647✔
1001
end
1002
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
1003
    @_noub_if_noinbounds_meta
713,160,402✔
1004
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
2,147,483,647✔
1005
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
2,147,483,647✔
1006
    return A
2,147,483,647✔
1007
end
1008
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,511✔
1009
    @_propagate_inbounds_meta
72,421,906✔
1010
    x = x isa T ? x : convert(T, x)::T
72,422,804✔
1011
    return _setindex!(A, x, i1, i2, I...)
75,602,479✔
1012
end
1013
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
4✔
1014
    @inline
72,416,482✔
1015
    @_noub_if_noinbounds_meta
72,416,482✔
1016
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
75,602,509✔
1017
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
75,602,491✔
1018
    return A
75,602,491✔
1019
end
1020

1021
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
1,701,681✔
1022
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
428,524,277✔
1023
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
491,032✔
1024
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
2,147,483,647✔
1025
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
1026
    __safe_setindex!(A, convert(T, x)::T, i))
36,101✔
1027

1028
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1029
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
91✔
1030
    @_propagate_inbounds_meta
817,671✔
1031
    @boundscheck setindex_shape_check(X, length(I))
10,187,774✔
1032
    @boundscheck checkbounds(A, I)
10,187,774✔
1033
    require_one_based_indexing(X)
817,671✔
1034
    X′ = unalias(A, X)
817,671✔
1035
    I′ = unalias(A, I)
817,671✔
1036
    count = 1
817,671✔
1037
    for i in I′
10,188,848✔
1038
        @inbounds A[i] = X′[count]
23,336,383✔
1039
        count += 1
23,336,383✔
1040
    end
37,962,742✔
1041
    return A
10,187,774✔
1042
end
1043

1044
# Faster contiguous setindex! with copyto!
1045
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
109✔
1046
    @inline
1,008,711✔
1047
    @boundscheck checkbounds(A, I)
1,009,027✔
1048
    lI = length(I)
1,009,027✔
1049
    @boundscheck setindex_shape_check(X, lI)
1,009,027✔
1050
    if lI > 0
1,009,027✔
1051
        unsafe_copyto!(A, first(I), X, 1, lI)
2,017,510✔
1052
    end
1053
    return A
1,009,027✔
1054
end
1055
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
40✔
1056
    @inline
74✔
1057
    lI = length(A)
74✔
1058
    @boundscheck setindex_shape_check(X, lI)
74✔
1059
    if lI > 0
74✔
1060
        unsafe_copyto!(A, 1, X, 1, lI)
148✔
1061
    end
1062
    return A
74✔
1063
end
1064

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

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

1083
function _growbeg!(a::Vector, delta::Integer)
38✔
1084
    @_noub_meta
19,864✔
1085
    delta = Int(delta)
19,864✔
1086
    delta == 0 && return # avoid attempting to index off the end
28,136,286✔
1087
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
28,135,714✔
1088
    ref = a.ref
84,905,148✔
1089
    mem = ref.mem
84,905,148✔
1090
    len = length(a)
84,905,148✔
1091
    offset = memoryrefoffset(ref)
84,905,148✔
1092
    newlen = len + delta
84,905,148✔
1093
    setfield!(a, :size, (newlen,))
84,905,148✔
1094
    # if offset is far enough advanced to fit data in existing memory without copying
1095
    if delta <= offset - 1
84,905,148✔
1096
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
55,594,905✔
1097
    else
1098
        @noinline (function()
58,620,496✔
1099
        @_terminates_locally_meta
12,332✔
1100
        memlen = length(mem)
29,310,254✔
1101
        if offset + len - 1 > memlen || offset < 1
58,620,508✔
1102
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1103
        end
1104
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1105
        # the +1 is because I didn't want to have an off by 1 error.
1106
        newmemlen = max(overallocation(len), len + 2 * delta + 1)
44,323,522✔
1107
        newoffset = div(newmemlen - newlen, 2) + 1
29,310,254✔
1108
        # If there is extra data after the end of the array we can use that space so long as there is enough
1109
        # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1110
        # Specifically, we want to ensure that we will only do this operation once before
1111
        # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1112
        if newoffset + newlen < memlen
29,310,254✔
1113
            newoffset = div(memlen - newlen, 2) + 1
27,406✔
1114
            newmem = mem
27,406✔
1115
            unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
50,652✔
1116
            for j in offset:newoffset+delta-1
27,406✔
1117
                @inbounds _unsetindex!(mem, j)
169,548✔
1118
            end
297,658✔
1119
        else
1120
            newmem = array_new_memory(mem, newmemlen)
58,565,696✔
1121
            unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
29,282,848✔
1122
        end
1123
        if ref !== a.ref
29,310,254✔
1124
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1125
        end
1126
        setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
29,310,254✔
1127
        end)()
1128
    end
1129
    return
84,905,148✔
1130
end
1131

1132
function _growend!(a::Vector, delta::Integer)
26✔
1133
    @_noub_meta
4,256,646✔
1134
    delta = Int(delta)
4,275,957✔
1135
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,386,157,483✔
1136
    ref = a.ref
2,147,483,647✔
1137
    mem = ref.mem
2,147,483,647✔
1138
    memlen = length(mem)
2,147,483,647✔
1139
    len = length(a)
2,147,483,647✔
1140
    newlen = len + delta
2,147,483,647✔
1141
    offset = memoryrefoffset(ref)
2,147,483,647✔
1142
    setfield!(a, :size, (newlen,))
2,147,483,647✔
1143
    newmemlen = offset + newlen - 1
2,147,483,647✔
1144
    if memlen < newmemlen
2,147,483,647✔
1145
        @noinline (function()
2,147,483,647✔
1146
        if offset + len - 1 > memlen || offset < 1
2,147,483,647✔
1147
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1148
        end
1149

1150
        if offset - 1 > div(5 * newlen, 4)
1,361,940,187✔
1151
            # If the offset is far enough that we can copy without resizing
1152
            # while maintaining proportional spacing on both ends of the array
1153
            # note that this branch prevents infinite growth when doing combinations
1154
            # of push! and popfirst! (i.e. when using a Vector as a queue)
1155
            newmem = mem
24,028✔
1156
            newoffset = div(newlen, 8) + 1
24,028✔
1157
        else
1158
            # grow either by our computed overallocation factor
1159
            # or exactly the requested size, whichever is larger
1160
            # TODO we should possibly increase the offset if the current offset is nonzero.
1161
            newmemlen2 = max(overallocation(memlen), newmemlen)
1,437,462,112✔
1162
            newmem = array_new_memory(mem, newmemlen2)
2,147,483,647✔
1163
            newoffset = offset
1,361,916,157✔
1164
        end
1165
        newref = @inbounds memoryref(newmem, newoffset)
1,361,940,185✔
1166
        unsafe_copyto!(newref, ref, len)
1,483,935,300✔
1167
        if ref !== a.ref
1,361,940,185✔
1168
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1169
        end
1170
        setfield!(a, :ref, newref)
1,361,940,185✔
1171
        end)()
1172
    end
1173
    return
2,147,483,647✔
1174
end
1175

1176
function _growat!(a::Vector, i::Integer, delta::Integer)
118,324,551✔
1177
    @_terminates_globally_noub_meta
185,346✔
1178
    delta = Int(delta)
185,346✔
1179
    i = Int(i)
185,346✔
1180
    i == 1 && return _growbeg!(a, delta)
118,324,551✔
1181
    len = length(a)
90,599,360✔
1182
    i == len + 1 && return _growend!(a, delta)
90,599,360✔
1183
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
90,530,397✔
1184
    1 < i <= len || throw(BoundsError(a, i))
90,530,399✔
1185
    ref = a.ref
90,530,395✔
1186
    mem = ref.mem
90,530,395✔
1187
    memlen = length(mem)
90,530,395✔
1188
    newlen = len + delta
90,530,395✔
1189
    offset = memoryrefoffset(ref)
90,530,395✔
1190
    setfield!(a, :size, (newlen,))
90,530,395✔
1191
    newmemlen = offset + newlen - 1
90,530,395✔
1192

1193
    # which side would we rather grow into?
1194
    prefer_start = i <= div(len, 2)
90,530,395✔
1195
    # if offset is far enough advanced to fit data in beginning of the memory
1196
    if prefer_start && delta <= offset - 1
90,530,395✔
1197
        newref = @inbounds memoryref(mem, offset - delta)
37,347,276✔
1198
        unsafe_copyto!(newref, ref, i)
74,694,552✔
1199
        setfield!(a, :ref, newref)
37,347,276✔
1200
        for j in i:i+delta-1
37,347,276✔
1201
            @inbounds _unsetindex!(a, j)
52,641,410✔
1202
        end
52,634,590✔
1203
    elseif !prefer_start && memlen >= newmemlen
53,183,119✔
1204
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
76,582,770✔
1205
        for j in i:i+delta-1
38,291,385✔
1206
            @inbounds _unsetindex!(a, j)
53,154,599✔
1207
        end
53,145,617✔
1208
    else
1209
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1210
        # the +1 is because I didn't want to have an off by 1 error.
1211
        newmemlen = max(overallocation(memlen), len+2*delta+1)
21,799,405✔
1212
        newoffset = (newmemlen - newlen) ÷ 2 + 1
14,891,734✔
1213
        newmem = array_new_memory(mem, newmemlen)
29,783,468✔
1214
        newref = @inbounds memoryref(newmem, newoffset)
14,891,734✔
1215
        unsafe_copyto!(newref, ref, i-1)
29,783,468✔
1216
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
29,783,468✔
1217
        setfield!(a, :ref, newref)
14,891,734✔
1218
    end
1219
end
1220

1221
# efficiently delete part of an array
1222
function _deletebeg!(a::Vector, delta::Integer)
23,473,324✔
1223
    delta = Int(delta)
1,081,282✔
1224
    len = length(a)
86,943,090✔
1225
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
86,943,090✔
1226
    for i in 1:delta
24,660,411✔
1227
        @inbounds _unsetindex!(a, i)
116,508,901✔
1228
    end
36,765,387✔
1229
    newlen = len - delta
86,943,090✔
1230
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
86,943,090✔
1231
        newref = @inbounds memoryref(a.ref, delta + 1)
79,136,210✔
1232
        setfield!(a, :ref, newref)
79,136,210✔
1233
    end
1234
    setfield!(a, :size, (newlen,))
86,943,090✔
1235
    return
86,943,090✔
1236
end
1237
function _deleteend!(a::Vector, delta::Integer)
25,906,839✔
1238
    delta = Int(delta)
6,507,305✔
1239
    len = length(a)
1,856,922,524✔
1240
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
1,856,922,524✔
1241
    newlen = len - delta
1,856,922,524✔
1242
    for i in newlen+1:len
1,904,746,137✔
1243
        @inbounds _unsetindex!(a, i)
2,147,483,647✔
1244
    end
2,147,483,647✔
1245
    setfield!(a, :size, (newlen,))
1,856,922,524✔
1246
    return
1,856,922,524✔
1247
end
1248
function _deleteat!(a::Vector, i::Integer, delta::Integer)
9,191,696✔
1249
    i = Int(i)
101,056✔
1250
    len = length(a)
9,191,696✔
1251
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
9,191,696✔
1252
    1 <= i <= len || throw(BoundsError(a, i))
9,191,699✔
1253
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
9,191,693✔
1254
    newa = a
101,043✔
1255
    if 2*i + delta <= len
9,191,693✔
1256
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
174,451✔
1257
        _deletebeg!(a, delta)
3,542,807✔
1258
    else
1259
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
12,233,350✔
1260
        _deleteend!(a, delta)
9,064,262✔
1261
    end
1262
    return
9,191,693✔
1263
end
1264
## Dequeue functionality ##
1265

1266
"""
1267
    push!(collection, items...) -> collection
1268

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

1272
# Examples
1273
```jldoctest
1274
julia> push!([1, 2, 3], 4, 5, 6)
1275
6-element Vector{Int64}:
1276
 1
1277
 2
1278
 3
1279
 4
1280
 5
1281
 6
1282
```
1283

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

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

1290
See also [`pushfirst!`](@ref).
1291
"""
1292
function push! end
1293

1294
function push!(a::Vector{T}, item) where T
4,652,224✔
1295
    @inline
9,617,387✔
1296
    # convert first so we don't grow the array if the assignment won't work
1297
    # and also to avoid a dynamic dynamic dispatch in the common case that
1298
    # `item` is poorly-typed and `a` is well-typed
1299
    item = item isa T ? item : convert(T, item)::T
51,934,286✔
1300
    return _push!(a, item)
2,147,483,647✔
1301
end
1302
function _push!(a::Vector{T}, item::T) where T
1303
    _growend!(a, 1)
2,147,483,647✔
1304
    @_safeindex a[length(a)] = item
2,147,483,647✔
1305
    return a
2,147,483,647✔
1306
end
1307

1308
# specialize and optimize the single argument case
1309
function push!(a::Vector{Any}, @nospecialize x)
8,293✔
1310
    _growend!(a, 1)
232,735,455✔
1311
    @_safeindex a[length(a)] = x
232,735,455✔
1312
    return a
232,735,455✔
1313
end
1314
function push!(a::Vector{Any}, @nospecialize x...)
16✔
1315
    @_terminates_locally_meta
18✔
1316
    na = length(a)
398,900✔
1317
    nx = length(x)
18✔
1318
    _growend!(a, nx)
398,900✔
1319
    @_safeindex for i = 1:nx
797,782✔
1320
        a[na+i] = x[i]
1,021,487✔
1321
    end
1,196,814✔
1322
    return a
398,900✔
1323
end
1324

1325
"""
1326
    append!(collection, collections...) -> collection.
1327

1328
For an ordered container `collection`, add the elements of each `collections`
1329
to the end of it.
1330

1331
!!! compat "Julia 1.6"
1332
    Specifying multiple collections to be appended requires at least Julia 1.6.
1333

1334
# Examples
1335
```jldoctest
1336
julia> append!([1], [2, 3])
1337
3-element Vector{Int64}:
1338
 1
1339
 2
1340
 3
1341

1342
julia> append!([1, 2, 3], [4, 5], [6])
1343
6-element Vector{Int64}:
1344
 1
1345
 2
1346
 3
1347
 4
1348
 5
1349
 6
1350
```
1351

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

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

1358
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1359
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1360
"""
1361
function append! end
1362

1363
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
8,442✔
1364
    items isa Tuple && (items = map(x -> convert(T, x), items))
2,251,750✔
1365
    n = length(items)
91,867,491✔
1366
    _growend!(a, n)
92,446,471✔
1367
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
143,430,405✔
1368
    return a
92,446,471✔
1369
end
1370

1371
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
94,334,235✔
1372
push!(a::AbstractVector, iter...) = append!(a, iter)
1,316,151✔
1373
append!(a::AbstractVector, iter...) = (for v in iter; append!(a, v); end; return a)
7✔
1374

1375
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
29,912,649✔
1376
    n = Int(length(iter))::Int
30,150,911✔
1377
    i = lastindex(a)
38✔
1378
    sizehint!(a, length(a) + n; shrink=false)
29,912,662✔
1379
    for item in iter
49,855,228✔
1380
        push!(a, item)
54,478,600✔
1381
    end
54,714,854✔
1382
    a
21✔
1383
end
1384
function _append!(a::AbstractVector, ::IteratorSize, iter)
64,421,571✔
1385
    for item in iter
78,749,931✔
1386
        push!(a, item)
64,235,817✔
1387
    end
64,235,823✔
1388
    a
4✔
1389
end
1390

1391
"""
1392
    prepend!(a::Vector, collections...) -> collection
1393

1394
Insert the elements of each `collections` to the beginning of `a`.
1395

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

1399
!!! compat "Julia 1.6"
1400
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1401

1402
# Examples
1403
```jldoctest
1404
julia> prepend!([3], [1, 2])
1405
3-element Vector{Int64}:
1406
 1
1407
 2
1408
 3
1409

1410
julia> prepend!([6], [1, 2], [3, 4, 5])
1411
6-element Vector{Int64}:
1412
 1
1413
 2
1414
 3
1415
 4
1416
 5
1417
 6
1418
```
1419
"""
1420
function prepend! end
1421

1422
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
2,154✔
1423
    items isa Tuple && (items = map(x -> convert(T, x), items))
5,122✔
1424
    n = length(items)
7,302✔
1425
    _growbeg!(a, n)
14,031✔
1426
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1427
    # just the last n elements instead of all of them from the first
1428
    copyto!(a, 1, items, lastindex(items)-n+1, n)
14,026✔
1429
    return a
7,302✔
1430
end
1431

1432
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
481✔
1433
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
15✔
1434
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
7✔
1435

1436
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
461✔
1437
    @_terminates_locally_meta
462✔
1438
    require_one_based_indexing(a)
462✔
1439
    n = Int(length(iter))::Int
462✔
1440
    sizehint!(a, length(a) + n; first=true, shrink=false)
462✔
1441
    n = 0
462✔
1442
    for item in iter
463✔
1443
        n += 1
761✔
1444
        pushfirst!(a, item)
762✔
1445
    end
757✔
1446
    reverse!(a, 1, n)
456✔
1447
    a
456✔
1448
end
1449
function _prepend!(a::Vector, ::IteratorSize, iter)
3✔
1450
    n = 0
3✔
1451
    for item in iter
5✔
1452
        n += 1
8✔
1453
        pushfirst!(a, item)
11✔
1454
    end
13✔
1455
    reverse!(a, 1, n)
2✔
1456
    a
2✔
1457
end
1458

1459
"""
1460
    resize!(a::Vector, n::Integer) -> Vector
1461

1462
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1463
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1464
guaranteed to be initialized.
1465

1466
# Examples
1467
```jldoctest
1468
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1469
3-element Vector{Int64}:
1470
 6
1471
 5
1472
 4
1473

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

1476
julia> length(a)
1477
8
1478

1479
julia> a[1:6]
1480
6-element Vector{Int64}:
1481
 6
1482
 5
1483
 4
1484
 3
1485
 2
1486
 1
1487
```
1488
"""
1489
function resize!(a::Vector, nl::Integer)
1,515,872,240✔
1490
    l = length(a)
1,582,626,734✔
1491
    if nl > l
1,582,626,734✔
1492
        _growend!(a, nl-l)
1,067,135,735✔
1493
    elseif nl != l
515,490,999✔
1494
        if nl < 0
134,482,754✔
1495
            _throw_argerror("new length must be ≥ 0")
2✔
1496
        end
1497
        _deleteend!(a, l-nl)
134,482,752✔
1498
    end
1499
    return a
1,582,626,729✔
1500
end
1501

1502
"""
1503
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1504

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

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

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

1518
See also [`resize!`](@ref).
1519

1520
# Notes on the performance model
1521

1522
For types that support `sizehint!`,
1523

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

1528
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1529
   `Base`.
1530

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

1533
!!! compat "Julia 1.11"
1534
    The `shrink` and `first` arguments were added in Julia 1.11.
1535
"""
1536
function sizehint! end
1537

1538
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
60,083,328✔
1539
    len = length(a)
30,040,888✔
1540
    ref = a.ref
30,040,888✔
1541
    mem = ref.mem
30,040,888✔
1542
    memlen = length(mem)
30,040,888✔
1543
    sz = max(Int(sz), len)
30,040,888✔
1544
    inc = sz - len
30,040,888✔
1545
    if sz <= memlen
30,040,888✔
1546
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1547
        if !shrink || memlen - sz <= div(memlen, 8)
26,288,086✔
1548
            return a
26,080,189✔
1549
        end
1550
        newmem = array_new_memory(mem, sz)
140,304✔
1551
        if first
95,238✔
1552
            newref = memoryref(newmem, inc + 1)
×
1553
        else
1554
            newref = memoryref(newmem)
95,238✔
1555
        end
1556
        unsafe_copyto!(newref, ref, len)
159,697✔
1557
        setfield!(a, :ref, newref)
95,238✔
1558
    elseif first
3,865,461✔
1559
        _growbeg!(a, inc)
914✔
1560
        newref = getfield(a, :ref)
457✔
1561
        newref = memoryref(newref, inc + 1)
457✔
1562
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
457✔
1563
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
457✔
1564
    else # last
1565
        _growend!(a, inc)
3,865,004✔
1566
        setfield!(a, :size, (len,)) # undo the size change from _growend!
3,865,004✔
1567
    end
1568
    a
6,764✔
1569
end
1570

1571
# Fall-back implementation for non-shrinkable collections
1572
# avoid defining this the normal way to avoid avoid infinite recursion
1573
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
2✔
1574
    get(kwargs, :first, false)::Bool
219✔
1575
    get(kwargs, :shrink, true)::Bool
219✔
1576
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
219✔
1577
    sizehint!(a, sz)
219✔
1578
end
1579

1580
"""
1581
    pop!(collection) -> item
1582

1583
Remove an item in `collection` and return it. If `collection` is an
1584
ordered container, the last item is returned; for unordered containers,
1585
an arbitrary element is returned.
1586

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

1589
# Examples
1590
```jldoctest
1591
julia> A=[1, 2, 3]
1592
3-element Vector{Int64}:
1593
 1
1594
 2
1595
 3
1596

1597
julia> pop!(A)
1598
3
1599

1600
julia> A
1601
2-element Vector{Int64}:
1602
 1
1603
 2
1604

1605
julia> S = Set([1, 2])
1606
Set{Int64} with 2 elements:
1607
  2
1608
  1
1609

1610
julia> pop!(S)
1611
2
1612

1613
julia> S
1614
Set{Int64} with 1 element:
1615
  1
1616

1617
julia> pop!(Dict(1=>2))
1618
1 => 2
1619
```
1620
"""
1621
function pop!(a::Vector)
22,202✔
1622
    if isempty(a)
1,616,136,378✔
1623
        _throw_argerror("array must be non-empty")
1✔
1624
    end
1625
    item = a[end]
1,616,136,377✔
1626
    _deleteend!(a, 1)
1,616,136,377✔
1627
    return item
1,616,136,377✔
1628
end
1629

1630
"""
1631
    popat!(a::Vector, i::Integer, [default])
1632

1633
Remove the item at the given `i` and return it. Subsequent items
1634
are shifted to fill the resulting gap.
1635
When `i` is not a valid index for `a`, return `default`, or throw an error if
1636
`default` is not specified.
1637

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

1640
!!! compat "Julia 1.5"
1641
    This function is available as of Julia 1.5.
1642

1643
# Examples
1644
```jldoctest
1645
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1646
3
1647

1648
julia> a
1649
3-element Vector{Int64}:
1650
 4
1651
 2
1652
 1
1653

1654
julia> popat!(a, 4, missing)
1655
missing
1656

1657
julia> popat!(a, 4)
1658
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1659
[...]
1660
```
1661
"""
1662
function popat!(a::Vector, i::Integer)
4✔
1663
    x = a[i]
10✔
1664
    _deleteat!(a, i, 1)
4✔
1665
    x
4✔
1666
end
1667

1668
function popat!(a::Vector, i::Integer, default)
2✔
1669
    if 1 <= i <= length(a)
2✔
1670
        x = @inbounds a[i]
1✔
1671
        _deleteat!(a, i, 1)
1✔
1672
        x
1✔
1673
    else
1674
        default
1✔
1675
    end
1676
end
1677

1678
"""
1679
    pushfirst!(collection, items...) -> collection
1680

1681
Insert one or more `items` at the beginning of `collection`.
1682

1683
This function is called `unshift` in many other programming languages.
1684

1685
# Examples
1686
```jldoctest
1687
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1688
6-element Vector{Int64}:
1689
 5
1690
 6
1691
 1
1692
 2
1693
 3
1694
 4
1695
```
1696
"""
1697
function pushfirst!(a::Vector{T}, item) where T
309✔
1698
    @inline
2,948✔
1699
    item = item isa T ? item : convert(T, item)::T
2,951✔
1700
    return _pushfirst!(a, item)
39,997✔
1701
end
1702
function _pushfirst!(a::Vector{T}, item::T) where T
1703
    _growbeg!(a, 1)
40,224✔
1704
    @_safeindex a[1] = item
36,499✔
1705
    return a
36,499✔
1706
end
1707

1708
# specialize and optimize the single argument case
1709
function pushfirst!(a::Vector{Any}, @nospecialize x)
27,748,114✔
1710
    _growbeg!(a, 1)
57,974,829✔
1711
    @_safeindex a[1] = x
56,734,763✔
1712
    return a
56,734,763✔
1713
end
1714
function pushfirst!(a::Vector{Any}, @nospecialize x...)
1✔
1715
    @_terminates_locally_meta
2✔
1716
    na = length(a)
2✔
1717
    nx = length(x)
2✔
1718
    _growbeg!(a, nx)
1,382✔
1719
    @_safeindex for i = 1:nx
1,380✔
1720
        a[i] = x[i]
1,384✔
1721
    end
2,077✔
1722
    return a
691✔
1723
end
1724

1725
"""
1726
    popfirst!(collection) -> item
1727

1728
Remove the first `item` from `collection`.
1729

1730
This function is called `shift` in many other programming languages.
1731

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

1734
# Examples
1735
```jldoctest
1736
julia> A = [1, 2, 3, 4, 5, 6]
1737
6-element Vector{Int64}:
1738
 1
1739
 2
1740
 3
1741
 4
1742
 5
1743
 6
1744

1745
julia> popfirst!(A)
1746
1
1747

1748
julia> A
1749
5-element Vector{Int64}:
1750
 2
1751
 3
1752
 4
1753
 5
1754
 6
1755
```
1756
"""
1757
function popfirst!(a::Vector)
27,748,423✔
1758
    if isempty(a)
86,787,603✔
1759
        _throw_argerror("array must be non-empty")
1✔
1760
    end
1761
    item = a[1]
86,787,602✔
1762
    _deletebeg!(a, 1)
86,787,602✔
1763
    return item
86,787,602✔
1764
end
1765

1766
"""
1767
    insert!(a::Vector, index::Integer, item)
1768

1769
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1770
the resulting `a`.
1771

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

1774
# Examples
1775
```jldoctest
1776
julia> insert!(Any[1:6;], 3, "here")
1777
7-element Vector{Any}:
1778
 1
1779
 2
1780
  "here"
1781
 3
1782
 4
1783
 5
1784
 6
1785
```
1786
"""
1787
function insert!(a::Array{T,1}, i::Integer, item) where T
299✔
1788
    @_propagate_inbounds_meta
1,209,845✔
1789
    item = item isa T ? item : convert(T, item)::T
1,209,860✔
1790
    return _insert!(a, i, item)
94,926,251✔
1791
end
1792
function _insert!(a::Array{T,1}, i::Integer, item::T) where T
1793
    @_noub_meta
1,209,820✔
1794
    # Throw convert error before changing the shape of the array
1795
    _growat!(a, i, 1)
94,926,251✔
1796
    # :noub, because _growat! already did bound check
1797
    @inbounds a[i] = item
94,926,249✔
1798
    return a
94,926,249✔
1799
end
1800

1801
"""
1802
    deleteat!(a::Vector, i::Integer)
1803

1804
Remove the item at the given `i` and return the modified `a`. Subsequent items
1805
are shifted to fill the resulting gap.
1806

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

1809
# Examples
1810
```jldoctest
1811
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1812
5-element Vector{Int64}:
1813
 6
1814
 4
1815
 3
1816
 2
1817
 1
1818
```
1819
"""
1820
function deleteat!(a::Vector, i::Integer)
290✔
1821
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,707✔
1822
    _deleteat!(a, i, 1)
8,964,505✔
1823
    return a
16,710✔
1824
end
1825

1826
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
34,070✔
1827
    if eltype(r) === Bool
75,593✔
1828
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1829
    else
1830
        n = length(a)
75,587✔
1831
        f = first(r)
75,682✔
1832
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
75,587✔
1833
        isempty(r) || _deleteat!(a, f, length(r))
431,522✔
1834
        return a
217,584✔
1835
    end
1836
end
1837

1838
"""
1839
    deleteat!(a::Vector, inds)
1840

1841
Remove the items at the indices given by `inds`, and return the modified `a`.
1842
Subsequent items are shifted to fill the resulting gap.
1843

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

1847
# Examples
1848
```jldoctest
1849
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1850
3-element Vector{Int64}:
1851
 5
1852
 3
1853
 1
1854

1855
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1856
3-element Vector{Int64}:
1857
 5
1858
 3
1859
 1
1860

1861
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1862
ERROR: ArgumentError: indices must be unique and sorted
1863
Stacktrace:
1864
[...]
1865
```
1866
"""
1867
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1868
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
113,749✔
1869

1870
struct Nowhere; end
1871
push!(::Nowhere, _) = nothing
×
1872
_growend!(::Nowhere, _) = nothing
×
1873

1874
function _push_deleted!(dltd, a::Vector, ind)
1875
    @_propagate_inbounds_meta
1,490,948✔
1876
    if isassigned(a, ind)
1,576,134✔
1877
        push!(dltd, a[ind])
1,576,133✔
1878
    else
1879
        _growend!(dltd, 1)
×
1880
    end
1881
end
1882

1883
function _copy_item!(a::Vector, p, q)
1884
    @_propagate_inbounds_meta
4,378,610✔
1885
    if isassigned(a, q)
4,425,353✔
1886
        a[p] = a[q]
4,425,352✔
1887
    else
1888
        _unsetindex!(a, p)
1✔
1889
    end
1890
end
1891

1892
function _deleteat!(a::Vector, inds, dltd=Nowhere())
113,769✔
1893
    n = length(a)
227,537✔
1894
    y = iterate(inds)
113,779✔
1895
    y === nothing && return a
113,769✔
1896
    (p, s) = y
35,464✔
1897
    checkbounds(a, p)
113,530✔
1898
    @inbounds _push_deleted!(dltd, a, p)
113,518✔
1899
    q = p+1
113,518✔
1900
    while true
1,576,134✔
1901
        y = iterate(inds, s)
1,576,145✔
1902
        y === nothing && break
1,576,134✔
1903
        (i,s) = y
1,455,490✔
1904
        if !(q <= i <= n)
1,462,618✔
1905
            if i < q
2✔
1906
                _throw_argerror("indices must be unique and sorted")
1✔
1907
            else
1908
                throw(BoundsError())
1✔
1909
            end
1910
        end
1911
        while q < i
2,888,819✔
1912
            @inbounds _copy_item!(a, p, q)
1,426,203✔
1913
            p += 1; q += 1
1,426,203✔
1914
        end
1,426,203✔
1915
        @inbounds _push_deleted!(dltd, a, i)
1,462,616✔
1916
        q = i+1
1,462,616✔
1917
    end
1,462,616✔
1918
    while q <= n
3,070,472✔
1919
        @inbounds _copy_item!(a, p, q)
2,956,956✔
1920
        p += 1; q += 1
2,956,956✔
1921
    end
2,956,956✔
1922
    _deleteend!(a, n-p+1)
1,576,132✔
1923
    return a
113,516✔
1924
end
1925

1926
# Simpler and more efficient version for logical indexing
1927
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1928
    n = length(a)
4,029✔
1929
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1930
    p = 1
4,024✔
1931
    for (q, i) in enumerate(inds)
8,047✔
1932
        @inbounds _copy_item!(a, p, q)
42,194✔
1933
        p += !i
42,194✔
1934
    end
80,365✔
1935
    _deleteend!(a, n-p+1)
21,353✔
1936
    return a
4,024✔
1937
end
1938

1939
const _default_splice = []
1940

1941
"""
1942
    splice!(a::Vector, index::Integer, [replacement]) -> item
1943

1944
Remove the item at the given index, and return the removed item.
1945
Subsequent items are shifted left to fill the resulting gap.
1946
If specified, replacement values from an ordered
1947
collection will be spliced in place of the removed item.
1948

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

1951
# Examples
1952
```jldoctest
1953
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1954
2
1955

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

1964
julia> splice!(A, 5, -1)
1965
1
1966

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

1975
julia> splice!(A, 1, [-1, -2, -3])
1976
6
1977

1978
julia> A
1979
7-element Vector{Int64}:
1980
 -1
1981
 -2
1982
 -3
1983
  5
1984
  4
1985
  3
1986
 -1
1987
```
1988

1989
To insert `replacement` before an index `n` without removing any items, use
1990
`splice!(collection, n:n-1, replacement)`.
1991
"""
1992
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,695✔
1993
    v = a[i]
3,712✔
1994
    m = length(ins)
3,426✔
1995
    if m == 0
3,426✔
1996
        _deleteat!(a, i, 1)
551✔
1997
    elseif m == 1
2,875✔
1998
        a[i] = only(ins)
266✔
1999
    else
2000
        _growat!(a, i, m-1)
2,609✔
2001
        k = 1
2,609✔
2002
        for x in ins
2,609✔
2003
            a[i+k-1] = x
335,634✔
2004
            k += 1
335,634✔
2005
        end
335,634✔
2006
    end
2007
    return v
3,426✔
2008
end
2009

2010
"""
2011
    splice!(a::Vector, indices, [replacement]) -> items
2012

2013
Remove items at specified indices, and return a collection containing
2014
the removed items.
2015
Subsequent items are shifted left to fill the resulting gaps.
2016
If specified, replacement values from an ordered collection will be spliced in
2017
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
2018

2019
To insert `replacement` before an index `n` without removing any items, use
2020
`splice!(collection, n:n-1, replacement)`.
2021

2022
$(_DOCS_ALIASING_WARNING)
2023

2024
!!! compat "Julia 1.5"
2025
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
2026

2027
!!! compat "Julia 1.8"
2028
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
2029

2030
# Examples
2031
```jldoctest
2032
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
2033
Int64[]
2034

2035
julia> A
2036
8-element Vector{Int64}:
2037
 -1
2038
 -2
2039
 -3
2040
  2
2041
  5
2042
  4
2043
  3
2044
 -1
2045
```
2046
"""
2047
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
23,479,507✔
2048
    v = a[r]
23,549,737✔
2049
    m = length(ins)
71,650✔
2050
    if m == 0
71,650✔
2051
        deleteat!(a, r)
74,059✔
2052
        return v
37,090✔
2053
    end
2054

2055
    n = length(a)
23,408,479✔
2056
    f = first(r)
23,408,479✔
2057
    l = last(r)
23,408,479✔
2058
    d = length(r)
23,408,479✔
2059

2060
    if m < d
23,408,479✔
2061
        delta = d - m
12,690✔
2062
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
19,149✔
2063
    elseif m > d
23,395,789✔
2064
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
23,395,671✔
2065
    end
2066

2067
    k = 1
34,560✔
2068
    for x in ins
23,419,985✔
2069
        a[f+k-1] = x
74,153,809✔
2070
        k += 1
74,153,809✔
2071
    end
98,871,708✔
2072
    return v
23,408,479✔
2073
end
2074

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

2077
function empty!(a::Vector)
4,586,115✔
2078
    _deleteend!(a, length(a))
112,497,615✔
2079
    return a
97,061,280✔
2080
end
2081

2082
# use memcmp for cmp on byte arrays
2083
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
2084
    aref = a.ref
3✔
2085
    bref = b.ref
3✔
2086
    ta = @_gc_preserve_begin aref
3✔
2087
    tb = @_gc_preserve_begin bref
3✔
2088
    pa = unsafe_convert(Ptr{Cvoid}, aref)
3✔
2089
    pb = unsafe_convert(Ptr{Cvoid}, bref)
3✔
2090
    c = memcmp(pa, pb, min(length(a),length(b)))
3✔
2091
    @_gc_preserve_end ta
3✔
2092
    @_gc_preserve_end tb
3✔
2093
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
2094
end
2095

2096
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2097
# use memcmp for == on bit integer types
2098
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,485✔
2099
    if size(a) == size(b)
4,253✔
2100
        aref = a.ref
2,157✔
2101
        bref = b.ref
2,157✔
2102
        ta = @_gc_preserve_begin aref
2,157✔
2103
        tb = @_gc_preserve_begin bref
2,157✔
2104
        pa = unsafe_convert(Ptr{Cvoid}, aref)
2,157✔
2105
        pb = unsafe_convert(Ptr{Cvoid}, bref)
2,157✔
2106
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
2,157✔
2107
        @_gc_preserve_end ta
2,157✔
2108
        @_gc_preserve_end tb
2,157✔
2109
        return c == 0
2,157✔
2110
    else
2111
        return false
×
2112
    end
2113
end
2114

2115
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
5,798✔
2116
    len = length(a)
66,074✔
2117
    if len == length(b)
66,074✔
2118
        aref = a.ref
65,950✔
2119
        bref = b.ref
33,032✔
2120
        ta = @_gc_preserve_begin aref
65,950✔
2121
        tb = @_gc_preserve_begin bref
65,950✔
2122
        T = eltype(Arr)
14,055✔
2123
        pa = unsafe_convert(Ptr{T}, aref)
65,950✔
2124
        pb = unsafe_convert(Ptr{T}, bref)
65,950✔
2125
        c = memcmp(pa, pb, sizeof(T) * len)
65,950✔
2126
        @_gc_preserve_end ta
65,950✔
2127
        @_gc_preserve_end tb
65,950✔
2128
        return c == 0
65,950✔
2129
    else
2130
        return false
124✔
2131
    end
2132
end
2133

2134
"""
2135
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2136

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

2140
# Examples
2141
```jldoctest
2142
julia> A = Vector(1:5)
2143
5-element Vector{Int64}:
2144
 1
2145
 2
2146
 3
2147
 4
2148
 5
2149

2150
julia> reverse(A)
2151
5-element Vector{Int64}:
2152
 5
2153
 4
2154
 3
2155
 2
2156
 1
2157

2158
julia> reverse(A, 1, 4)
2159
5-element Vector{Int64}:
2160
 4
2161
 3
2162
 2
2163
 1
2164
 5
2165

2166
julia> reverse(A, 3, 5)
2167
5-element Vector{Int64}:
2168
 1
2169
 2
2170
 5
2171
 4
2172
 3
2173
```
2174
"""
2175
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
8,558✔
2176
    s, n = Int(start), Int(stop)
949✔
2177
    B = similar(A)
16,843✔
2178
    for i = firstindex(A):s-1
8,559✔
2179
        B[i] = A[i]
1,684✔
2180
    end
3,078✔
2181
    for i = s:n
8,571✔
2182
        B[i] = A[n+s-i]
292,044✔
2183
    end
575,543✔
2184
    for i = n+1:lastindex(A)
16,826✔
2185
        B[i] = A[i]
1,690✔
2186
    end
3,090✔
2187
    return B
8,558✔
2188
end
2189

2190
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2191
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2192
    @eval begin
2193
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
212,902,002✔
2194
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
8,764,029✔
2195
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2196
        function $_f(A::AbstractVector, dim::Integer)
2197
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
2198
            return $_f(A, :)
4✔
2199
        end
2200
    end
2201
end
2202

2203
function reverseind(a::AbstractVector, i::Integer)
3✔
2204
    li = LinearIndices(a)
3✔
2205
    first(li) + last(li) - i
3✔
2206
end
2207

2208
# This implementation of `midpoint` is performance-optimized but safe
2209
# only if `lo <= hi`.
2210
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
54,513,848✔
2211
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2212

2213
"""
2214
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2215

2216
In-place version of [`reverse`](@ref).
2217

2218
# Examples
2219
```jldoctest
2220
julia> A = Vector(1:5)
2221
5-element Vector{Int64}:
2222
 1
2223
 2
2224
 3
2225
 4
2226
 5
2227

2228
julia> reverse!(A);
2229

2230
julia> A
2231
5-element Vector{Int64}:
2232
 5
2233
 4
2234
 3
2235
 2
2236
 1
2237
```
2238
"""
2239
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
137,446,726✔
2240
    s, n = Int(start), Int(stop)
128,563,726✔
2241
    if n > s # non-empty and non-trivial
137,446,723✔
2242
        liv = LinearIndices(v)
36,362,189✔
2243
        if !(first(liv) ≤ s ≤ last(liv))
36,362,189✔
2244
            throw(BoundsError(v, s))
3✔
2245
        elseif !(first(liv) ≤ n ≤ last(liv))
36,362,186✔
2246
            throw(BoundsError(v, n))
1✔
2247
        end
2248
        r = n
42,712✔
2249
        @inbounds for i in s:midpoint(s, n-1)
36,362,185✔
2250
            v[i], v[r] = v[r], v[i]
50,002,982✔
2251
            r -= 1
50,002,982✔
2252
        end
63,643,779✔
2253
    end
2254
    return v
137,446,719✔
2255
end
2256

2257
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2258

2259
vcat() = Vector{Any}()
10,290✔
2260
hcat() = Vector{Any}()
1✔
2261

2262
function hcat(V::Vector{T}...) where T
62✔
2263
    height = length(V[1])
570✔
2264
    for j = 2:length(V)
570✔
2265
        if length(V[j]) != height
636✔
2266
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2267
        end
2268
    end
733✔
2269
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
569✔
2270
end
2271
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2272

2273
function vcat(arrays::Vector{T}...) where T
36,245✔
2274
    n = 0
4,420✔
2275
    for a in arrays
36,245✔
2276
        n += length(a)
2,072,836✔
2277
    end
2,109,075✔
2278
    arr = Vector{T}(undef, n)
72,467✔
2279
    nd = 1
4,420✔
2280
    for a in arrays
36,245✔
2281
        na = length(a)
2,072,836✔
2282
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,072,836✔
2283
        unsafe_copyto!(arr, nd, a, 1, na)
4,141,058✔
2284
        nd += na
2,072,836✔
2285
    end
2,109,075✔
2286
    return arr
36,245✔
2287
end
2288
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
34✔
2289

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

2292
## find ##
2293

2294
"""
2295
    findnext(A, i)
2296

2297
Find the next index after or including `i` of a `true` element of `A`,
2298
or `nothing` if not found.
2299

2300
Indices are of the same type as those returned by [`keys(A)`](@ref)
2301
and [`pairs(A)`](@ref).
2302

2303
# Examples
2304
```jldoctest
2305
julia> A = [false, false, true, false]
2306
4-element Vector{Bool}:
2307
 0
2308
 0
2309
 1
2310
 0
2311

2312
julia> findnext(A, 1)
2313
3
2314

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

2317
julia> A = [false false; true false]
2318
2×2 Matrix{Bool}:
2319
 0  0
2320
 1  0
2321

2322
julia> findnext(A, CartesianIndex(1, 1))
2323
CartesianIndex(2, 1)
2324
```
2325
"""
2326
findnext(A, start) = findnext(identity, A, start)
43,296✔
2327

2328
"""
2329
    findfirst(A)
2330

2331
Return the index or key of the first `true` value in `A`.
2332
Return `nothing` if no such value is found.
2333
To search for other kinds of values, pass a predicate as the first argument.
2334

2335
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2336
and [`pairs(A)`](@ref).
2337

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

2340
# Examples
2341
```jldoctest
2342
julia> A = [false, false, true, false]
2343
4-element Vector{Bool}:
2344
 0
2345
 0
2346
 1
2347
 0
2348

2349
julia> findfirst(A)
2350
3
2351

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

2354
julia> A = [false false; true false]
2355
2×2 Matrix{Bool}:
2356
 0  0
2357
 1  0
2358

2359
julia> findfirst(A)
2360
CartesianIndex(2, 1)
2361
```
2362
"""
2363
findfirst(A) = findfirst(identity, A)
2✔
2364

2365
# Needed for bootstrap, and allows defining only an optimized findnext method
2366
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
12,020✔
2367

2368
"""
2369
    findnext(predicate::Function, A, i)
2370

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

2376
Indices are of the same type as those returned by [`keys(A)`](@ref)
2377
and [`pairs(A)`](@ref).
2378

2379
# Examples
2380
```jldoctest
2381
julia> A = [1, 4, 2, 2];
2382

2383
julia> findnext(isodd, A, 1)
2384
1
2385

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

2388
julia> A = [1 4; 2 2];
2389

2390
julia> findnext(isodd, A, CartesianIndex(1, 1))
2391
CartesianIndex(1, 1)
2392

2393
julia> findnext(isspace, "a b c", 3)
2394
4
2395
```
2396
"""
2397
function findnext(testf::Function, A, start)
42,128✔
2398
    i = oftype(first(keys(A)), start)
45,175✔
2399
    l = last(keys(A))
96,071,533✔
2400
    i > l && return nothing
96,071,533✔
2401
    while true
208,902,163✔
2402
        testf(A[i]) && return i
208,923,302✔
2403
        i == l && break
199,884,068✔
2404
        # nextind(A, l) can throw/overflow
2405
        i = nextind(A, i)
194,611,175✔
2406
    end
194,611,156✔
2407
    return nothing
5,272,888✔
2408
end
2409

2410
"""
2411
    findfirst(predicate::Function, A)
2412

2413
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2414
Return `nothing` if there is no such element.
2415

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

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

2428
julia> findfirst(iseven, A)
2429
2
2430

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

2433
julia> findfirst(isequal(4), A)
2434
2
2435

2436
julia> A = [1 4; 2 2]
2437
2×2 Matrix{Int64}:
2438
 1  4
2439
 2  2
2440

2441
julia> findfirst(iseven, A)
2442
CartesianIndex(2, 1)
2443
```
2444
"""
2445
function findfirst(testf::Function, A)
15✔
2446
    for (i, a) in pairs(A)
22✔
2447
        testf(a) && return i
14✔
2448
    end
11✔
2449
    return nothing
8✔
2450
end
2451

2452
# Needed for bootstrap, and allows defining only an optimized findnext method
2453
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
305,810,320✔
2454
    findnext(testf, A, first(keys(A)))
2455

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

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

2462
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2463
    isempty(r) && return nothing
6✔
2464
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2465
    d = convert(S, p.x - first(r))::S
3✔
2466
    iszero(d % step(r)) || return nothing
3✔
2467
    return d ÷ step(r) + 1
3✔
2468
end
2469

2470
"""
2471
    findprev(A, i)
2472

2473
Find the previous index before or including `i` of a `true` element of `A`,
2474
or `nothing` if not found.
2475

2476
Indices are of the same type as those returned by [`keys(A)`](@ref)
2477
and [`pairs(A)`](@ref).
2478

2479
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2480

2481
# Examples
2482
```jldoctest
2483
julia> A = [false, false, true, true]
2484
4-element Vector{Bool}:
2485
 0
2486
 0
2487
 1
2488
 1
2489

2490
julia> findprev(A, 3)
2491
3
2492

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

2495
julia> A = [false false; true true]
2496
2×2 Matrix{Bool}:
2497
 0  0
2498
 1  1
2499

2500
julia> findprev(A, CartesianIndex(2, 1))
2501
CartesianIndex(2, 1)
2502
```
2503
"""
2504
findprev(A, start) = findprev(identity, A, start)
8,326✔
2505

2506
"""
2507
    findlast(A)
2508

2509
Return the index or key of the last `true` value in `A`.
2510
Return `nothing` if there is no `true` value in `A`.
2511

2512
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2513
and [`pairs(A)`](@ref).
2514

2515
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2516

2517
# Examples
2518
```jldoctest
2519
julia> A = [true, false, true, false]
2520
4-element Vector{Bool}:
2521
 1
2522
 0
2523
 1
2524
 0
2525

2526
julia> findlast(A)
2527
3
2528

2529
julia> A = falses(2,2);
2530

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

2533
julia> A = [true false; true false]
2534
2×2 Matrix{Bool}:
2535
 1  0
2536
 1  0
2537

2538
julia> findlast(A)
2539
CartesianIndex(2, 1)
2540
```
2541
"""
2542
findlast(A) = findlast(identity, A)
23✔
2543

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

2547
"""
2548
    findprev(predicate::Function, A, i)
2549

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

2555
Indices are of the same type as those returned by [`keys(A)`](@ref)
2556
and [`pairs(A)`](@ref).
2557

2558
# Examples
2559
```jldoctest
2560
julia> A = [4, 6, 1, 2]
2561
4-element Vector{Int64}:
2562
 4
2563
 6
2564
 1
2565
 2
2566

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

2569
julia> findprev(isodd, A, 3)
2570
3
2571

2572
julia> A = [4 6; 1 2]
2573
2×2 Matrix{Int64}:
2574
 4  6
2575
 1  2
2576

2577
julia> findprev(isodd, A, CartesianIndex(1, 2))
2578
CartesianIndex(2, 1)
2579

2580
julia> findprev(isspace, "a b c", 3)
2581
2
2582
```
2583
"""
2584
function findprev(testf::Function, A, start)
311✔
2585
    f = first(keys(A))
36,934✔
2586
    i = oftype(f, start)
36,945✔
2587
    i < f && return nothing
38,632✔
2588
    while true
181,853✔
2589
        testf(A[i]) && return i
182,159✔
2590
        i == f && break
143,359✔
2591
        # prevind(A, f) can throw/underflow
2592
        i = prevind(A, i)
143,250✔
2593
    end
143,222✔
2594
    return nothing
106✔
2595
end
2596

2597
"""
2598
    findlast(predicate::Function, A)
2599

2600
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2601
Return `nothing` if there is no such element.
2602

2603
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2604
and [`pairs(A)`](@ref).
2605

2606
# Examples
2607
```jldoctest
2608
julia> A = [1, 2, 3, 4]
2609
4-element Vector{Int64}:
2610
 1
2611
 2
2612
 3
2613
 4
2614

2615
julia> findlast(isodd, A)
2616
3
2617

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

2620
julia> A = [1 2; 3 4]
2621
2×2 Matrix{Int64}:
2622
 1  2
2623
 3  4
2624

2625
julia> findlast(isodd, A)
2626
CartesianIndex(2, 1)
2627
```
2628
"""
2629
function findlast(testf::Function, A)
3✔
2630
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2631
        testf(a) && return i
6✔
2632
    end
6✔
2633
    return nothing
2✔
2634
end
2635

2636
# Needed for bootstrap, and allows defining only an optimized findprev method
2637
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
15,387✔
2638
    findprev(testf, A, last(keys(A)))
2639

2640
"""
2641
    findall(f::Function, A)
2642

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

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

2649
# Examples
2650
```jldoctest
2651
julia> x = [1, 3, 4]
2652
3-element Vector{Int64}:
2653
 1
2654
 3
2655
 4
2656

2657
julia> findall(isodd, x)
2658
2-element Vector{Int64}:
2659
 1
2660
 2
2661

2662
julia> A = [1 2 0; 3 4 0]
2663
2×3 Matrix{Int64}:
2664
 1  2  0
2665
 3  4  0
2666
julia> findall(isodd, A)
2667
2-element Vector{CartesianIndex{2}}:
2668
 CartesianIndex(1, 1)
2669
 CartesianIndex(2, 1)
2670

2671
julia> findall(!iszero, A)
2672
4-element Vector{CartesianIndex{2}}:
2673
 CartesianIndex(1, 1)
2674
 CartesianIndex(2, 1)
2675
 CartesianIndex(1, 2)
2676
 CartesianIndex(2, 2)
2677

2678
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2679
Dict{Symbol, Int64} with 3 entries:
2680
  :A => 10
2681
  :B => -1
2682
  :C => 0
2683

2684
julia> findall(≥(0), d)
2685
2-element Vector{Symbol}:
2686
 :A
2687
 :C
2688

2689
```
2690
"""
2691
function findall(testf::Function, A)
24✔
2692
    gen = (first(p) for p in pairs(A) if testf(last(p)))
39✔
2693
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
39✔
2694
end
2695

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

2700
"""
2701
    findall(A)
2702

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

2707
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2708
and [`pairs(A)`](@ref).
2709

2710
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2711

2712
# Examples
2713
```jldoctest
2714
julia> A = [true, false, false, true]
2715
4-element Vector{Bool}:
2716
 1
2717
 0
2718
 0
2719
 1
2720

2721
julia> findall(A)
2722
2-element Vector{Int64}:
2723
 1
2724
 4
2725

2726
julia> A = [true false; false true]
2727
2×2 Matrix{Bool}:
2728
 1  0
2729
 0  1
2730

2731
julia> findall(A)
2732
2-element Vector{CartesianIndex{2}}:
2733
 CartesianIndex(1, 1)
2734
 CartesianIndex(2, 2)
2735

2736
julia> findall(falses(3))
2737
Int64[]
2738
```
2739
"""
2740
function findall(A)
4✔
2741
    collect(first(p) for p in pairs(A) if last(p))
4✔
2742
end
2743

2744
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2745
function findall(A::AbstractArray{Bool})
823✔
2746
    n = count(A)
3,679✔
2747
    I = Vector{eltype(keys(A))}(undef, n)
6,976✔
2748
    cnt = 1
3,674✔
2749
    for (i,a) in pairs(A)
7,340✔
2750
        if a
208,418✔
2751
            I[cnt] = i
126,816✔
2752
            cnt += 1
126,816✔
2753
        end
2754
    end
413,167✔
2755
    I
3,674✔
2756
end
2757

2758
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2759
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2760
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2761

2762
# similar to Matlab's ismember
2763
"""
2764
    indexin(a, b)
2765

2766
Return an array containing the first index in `b` for
2767
each value in `a` that is a member of `b`. The output
2768
array contains `nothing` wherever `a` is not a member of `b`.
2769

2770
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2771

2772
# Examples
2773
```jldoctest
2774
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2775

2776
julia> b = ['a', 'b', 'c'];
2777

2778
julia> indexin(a, b)
2779
6-element Vector{Union{Nothing, Int64}}:
2780
 1
2781
 2
2782
 3
2783
 2
2784
  nothing
2785
 1
2786

2787
julia> indexin(b, a)
2788
3-element Vector{Union{Nothing, Int64}}:
2789
 1
2790
 2
2791
 3
2792
```
2793
"""
2794
function indexin(a, b::AbstractArray)
7✔
2795
    inds = keys(b)
7✔
2796
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2797
    for (val, ind) in zip(b, inds)
14✔
2798
        get!(bdict, val, ind)
30✔
2799
    end
53✔
2800
    return Union{eltype(inds), Nothing}[
7✔
2801
        get(bdict, i, nothing) for i in a
2802
    ]
2803
end
2804

2805
function _findin(a::Union{AbstractArray, Tuple}, b)
375✔
2806
    ind  = Vector{eltype(keys(a))}()
561✔
2807
    bset = Set(b)
377✔
2808
    @inbounds for (i,ai) in pairs(a)
606✔
2809
        ai in bset && push!(ind, i)
90,559✔
2810
    end
180,565✔
2811
    ind
375✔
2812
end
2813

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

2859
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2860
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2861
        return _sortedfindin(x, pred.x)
9✔
2862
    else
2863
        return _findin(x, pred.x)
6✔
2864
    end
2865
end
2866
# issorted fails for some element types so the method above has to be restricted
2867
# to element with isless/< defined.
2868
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
373✔
2869
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2870

2871
# Copying subregions
2872
function indcopy(sz::Dims, I::Vector)
1✔
2873
    n = length(I)
1✔
2874
    s = sz[n]
1✔
2875
    for i = n+1:length(sz)
2✔
2876
        s *= sz[i]
×
2877
    end
×
2878
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2879
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2880
    dst, src
1✔
2881
end
2882

2883
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2884
    n = length(I)
1✔
2885
    s = sz[n]
1✔
2886
    for i = n+1:length(sz)
1✔
2887
        s *= sz[i]
×
2888
    end
×
2889
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2890
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2891
    dst, src
1✔
2892
end
2893

2894
## Filter ##
2895

2896
"""
2897
    filter(f, a)
2898

2899
Return a copy of collection `a`, removing elements for which `f` is `false`.
2900
The function `f` is passed one argument.
2901

2902
!!! compat "Julia 1.4"
2903
    Support for `a` as a tuple requires at least Julia 1.4.
2904

2905
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2906

2907
# Examples
2908
```jldoctest
2909
julia> a = 1:10
2910
1:10
2911

2912
julia> filter(isodd, a)
2913
5-element Vector{Int64}:
2914
 1
2915
 3
2916
 5
2917
 7
2918
 9
2919
```
2920
"""
2921
function filter(f, a::Array{T, N}) where {T, N}
18,689✔
2922
    j = 1
16,146✔
2923
    b = Vector{T}(undef, length(a))
37,258✔
2924
    for ai in a
18,689✔
2925
        @inbounds b[j] = ai
3,250,573✔
2926
        j = ifelse(f(ai)::Bool, j+1, j)
3,252,228✔
2927
    end
3,250,573✔
2928
    resize!(b, j-1)
18,689✔
2929
    sizehint!(b, length(b))
18,689✔
2930
    b
16,146✔
2931
end
2932

2933
function filter(f, a::AbstractArray)
454✔
2934
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
454✔
2935

2936
    j = 1
454✔
2937
    idxs = Vector{Int}(undef, length(a))
746✔
2938
    for idx in eachindex(a)
457✔
2939
        @inbounds idxs[j] = idx
103,441✔
2940
        ai = @inbounds a[idx]
103,441✔
2941
        j = ifelse(f(ai)::Bool, j+1, j)
104,974✔
2942
    end
206,589✔
2943
    resize!(idxs, j-1)
453✔
2944
    res = a[idxs]
453✔
2945
    empty!(idxs)
4,128✔
2946
    sizehint!(idxs, 0)
453✔
2947
    return res
453✔
2948
end
2949

2950
"""
2951
    filter!(f, a)
2952

2953
Update collection `a`, removing elements for which `f` is `false`.
2954
The function `f` is passed one argument.
2955

2956
# Examples
2957
```jldoctest
2958
julia> filter!(isodd, Vector(1:10))
2959
5-element Vector{Int64}:
2960
 1
2961
 3
2962
 5
2963
 7
2964
 9
2965
```
2966
"""
2967
function filter!(f, a::AbstractVector)
999,171✔
2968
    j = firstindex(a)
1,137✔
2969
    for ai in a
133,519,090✔
2970
        @inbounds a[j] = ai
153,952,369✔
2971
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
155,815,876✔
2972
    end
153,952,378✔
2973
    j > lastindex(a) && return a
133,519,089✔
2974
    if a isa Vector
410✔
2975
        resize!(a, j-1)
73,835✔
2976
        sizehint!(a, j-1)
73,835✔
2977
    else
2978
        deleteat!(a, j:lastindex(a))
1✔
2979
    end
2980
    return a
73,836✔
2981
end
2982

2983
"""
2984
    filter(f)
2985

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

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

2992
# Examples
2993
```jldoctest
2994
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2995
(1, 2, 4, 6)
2996

2997
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2998
3-element Vector{Vector{Int64}}:
2999
 [2]
3000
 [2, 4]
3001
 [4]
3002
```
3003
!!! compat "Julia 1.9"
3004
    This method requires at least Julia 1.9.
3005
"""
3006
function filter(f)
1✔
3007
    Fix1(filter, f)
1✔
3008
end
3009

3010
"""
3011
    keepat!(a::Vector, inds)
3012
    keepat!(a::BitVector, inds)
3013

3014
Remove the items at all the indices which are not given by `inds`,
3015
and return the modified `a`.
3016
Items which are kept are shifted to fill the resulting gaps.
3017

3018
$(_DOCS_ALIASING_WARNING)
3019

3020
`inds` must be an iterator of sorted and unique integer indices.
3021
See also [`deleteat!`](@ref).
3022

3023
!!! compat "Julia 1.7"
3024
    This function is available as of Julia 1.7.
3025

3026
# Examples
3027
```jldoctest
3028
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
3029
3-element Vector{Int64}:
3030
 6
3031
 4
3032
 2
3033
```
3034
"""
3035
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
3036

3037
"""
3038
    keepat!(a::Vector, m::AbstractVector{Bool})
3039
    keepat!(a::BitVector, m::AbstractVector{Bool})
3040

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

3045
# Examples
3046
```jldoctest
3047
julia> a = [:a, :b, :c];
3048

3049
julia> keepat!(a, [true, false, true])
3050
2-element Vector{Symbol}:
3051
 :a
3052
 :c
3053

3054
julia> a
3055
2-element Vector{Symbol}:
3056
 :a
3057
 :c
3058
```
3059
"""
3060
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
3061

3062
# set-like operators for vectors
3063
# These are moderately efficient, preserve order, and remove dupes.
3064

3065
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
398,294✔
3066
    # P, U force specialization
3067
    if pred(x, state)
783,635✔
3068
        update!(state, x)
19,128✔
3069
        true
3070
    else
3071
        false
3072
    end
3073
end
3074

3075
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
277✔
3076
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
4,276✔
3077

3078
function _grow!(pred!, v::AbstractVector, itrs)
108✔
3079
    filter!(pred!, v) # uniquify v
304✔
3080
    for itr in itrs
304✔
3081
        mapfilter(pred!, push!, itr, v)
595✔
3082
    end
879✔
3083
    return v
304✔
3084
end
3085

3086
union!(v::AbstractVector{T}, itrs...) where {T} =
272✔
3087
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3088

3089
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
3090
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3091

3092
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
2✔
3093
    seen = Set{eltype(v)}()
6✔
3094
    filter!(_grow_filter!(seen), v)
6✔
3095
    shrinker!(seen, itrs...)
6✔
3096
    filter!(in(seen), v)
6✔
3097
end
3098

3099
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
3100
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
3101

3102
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
4,244✔
3103

3104
function _shrink(shrinker!::F, itr, itrs) where F
4,147✔
3105
    T = promote_eltype(itr, itrs...)
4,092✔
3106
    keep = shrinker!(Set{T}(itr), itrs...)
5,207✔
3107
    vectorfilter(T, _shrink_filter!(keep), itr)
4,185✔
3108
end
3109

3110
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
465✔
3111
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
3,720✔
3112

3113
function intersect(v::AbstractVector, r::AbstractRange)
7✔
3114
    T = promote_eltype(v, r)
11✔
3115
    common = Iterators.filter(in(r), v)
59✔
3116
    seen = Set{T}(common)
59✔
3117
    return vectorfilter(T, _shrink_filter!(seen), common)
59✔
3118
end
3119
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
3120

3121
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3122
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
3,852✔
3123
    if i isa Bool # Not via dispatch to avoid ambiguities
29,737,916✔
3124
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3125
    else
3126
        _getindex(v, i)
595,631,138✔
3127
    end
3128
end
3129

3130
"""
3131
    wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
3132

3133
Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version
3134
of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers.
3135
"""
3136
function wrap end
3137

3138
# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller
3139
function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N}
212✔
3140
    mem = ref.mem
5,897,132✔
3141
    mem_len = length(mem) + 1 - memoryrefoffset(ref)
5,897,132✔
3142
    len = Core.checked_dims(dims...)
222✔
3143
    @boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len)
5,897,135✔
3144
    if N != 1 && !(ref === GenericMemoryRef(mem) && len === mem_len)
9✔
3145
        mem = ccall(:jl_genericmemory_slice, Memory{T}, (Any, Ptr{Cvoid}, Int), mem, ref.ptr_or_offset, len)
3✔
3146
        ref = memoryref(mem)
3✔
3147
    end
3148
    return ref
5,897,129✔
3149
end
3150

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

3156
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
4✔
3157
    dims = convert(Dims, dims)
4✔
3158
    ref = _wrap(m, dims)
4✔
3159
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
4✔
3160
end
3161

3162
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
3✔
3163
    dims = convert(Dims, dims)
3✔
3164
    ref = _wrap(memoryref(m), dims)
4✔
3165
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
2✔
3166
end
3167
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
4✔
3168
    dims = (Int(l),)
5,896,914✔
3169
    ref = _wrap(m, dims)
5,896,916✔
3170
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
757,839✔
3171
end
3172
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
1✔
3173
    dims = (Int(l),)
1✔
3174
    ref = _wrap(memoryref(m), (l,))
1✔
3175
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
1✔
3176
end
3177
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
3178
    ref = memoryref(m)
1,587,909✔
3179
    dims = (length(m),)
1,587,909✔
3180
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
1,557,083✔
3181
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