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

JuliaLang / julia / #37749

15 Apr 2024 07:40AM UTC coverage: 87.242% (-0.02%) from 87.265%
#37749

push

local

web-flow
Don't use `do` as variable name in doc strings. (#53924)

75989 of 87101 relevant lines covered (87.24%)

16012970.01 hits per line

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

93.98
/base/array.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
## array.jl: Dense arrays
4

5
"""
6
    DimensionMismatch([msg])
7

8
The objects called do not have matching dimensionality. Optional argument `msg` is a
9
descriptive error string.
10
"""
11
struct DimensionMismatch <: Exception
12
    msg::AbstractString
13,569✔
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}()
34,637,696✔
159
function vect(X::T...) where T
50,731✔
160
    @_terminates_locally_meta
104,265✔
161
    vec = Vector{T}(undef, length(X))
1,738,003✔
162
    @_safeindex for i = 1:length(X)
231,826✔
163
        vec[i] = X[i]
4,844,787✔
164
    end
6,499,242✔
165
    return vec
186,830✔
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,775✔
184
    T = promote_typeof(X...)
57,153✔
185
    return T[X...]
57,333✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
10,560✔
190
    d < 1 && error("arraysize: dimension out of range")
61,409,851✔
191
    sz = getfield(a, :size)
61,529,192✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
85,694,975✔
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))
78,990✔
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)
52,481✔
215

216
function _unsetindex!(A::Array, i::Int)
217
    @inline
10,982,906✔
218
    @boundscheck checkbounds(A, i)
2,147,483,647✔
219
    @inbounds _unsetindex!(GenericMemoryRef(A.ref, i))
2,147,483,647✔
220
    return A
2,147,483,647✔
221
end
222
function _unsetindex!(A::Array, i::Int...)
223
    @inline
8✔
224
    @boundscheck checkbounds(A, i...)
8✔
225
    @inbounds _unsetindex!(A, _to_linear_index(A, i...))
8✔
226
    return A
8✔
227
end
228

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

240
sizeof(a::Array) = length(a) * elsize(typeof(a)) # n.b. this ignores bitsunion bytes, as a historical fact
2,776,571✔
241

242
function isassigned(a::Array, i::Int...)
110,361✔
243
    @inline
3,760,941✔
244
    @_noub_if_noinbounds_meta
3,760,941✔
245
    @boundscheck checkbounds(Bool, a, i...) || return false
3,760,953✔
246
    ii = _sub2ind(size(a), i...)
3,760,933✔
247
    return @inbounds isassigned(memoryref(a.ref, ii, false))
3,760,933✔
248
end
249

250
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
165✔
251
    @inline
26,699,228✔
252
    @_noub_if_noinbounds_meta
26,699,228✔
253
    @boundscheck checkbounds(Bool, a, i) || return false
2,147,483,647✔
254
    return @inbounds isassigned(memoryref(a.ref, i, false))
2,147,483,647✔
255
end
256

257

258
## copy ##
259

260
"""
261
    unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
262

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

266
The `unsafe` prefix on this function indicates that no validation is performed on the
267
pointers `dest` and `src` to ensure that they are valid. Incorrect usage may corrupt or
268
segfault your program, in the same manner as C.
269
"""
270
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
271
    # Do not use this to copy data between pointer arrays.
272
    # It can't be made safe no matter how carefully you checked.
273
    memmove(dest, src, n * aligned_sizeof(T))
28,450,301✔
274
    return dest
27,650,604✔
275
end
276

277
"""
278
    unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
279

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

283
The `unsafe` prefix on this function indicates that no validation is performed to ensure
284
that n is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
285
the same manner as C.
286
"""
287
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
288
    n == 0 && return dest
13,062,509✔
289
    unsafe_copyto!(GenericMemoryRef(dest.ref, doffs), GenericMemoryRef(src.ref, soffs), n)
16,116,660✔
290
    return dest
8,058,333✔
291
end
292

293
"""
294
    copyto!(dest, doffs, src, soffs, n)
295

296
Copy `n` elements from collection `src` starting at the linear index `soffs`, to array `dest` starting at
297
the index `doffs`. Return `dest`.
298
"""
299
copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
78,052✔
300
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
16✔
301
copyto!(dest::Memory, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
×
302

303
# this is only needed to avoid possible ambiguities with methods added in some packages
304
copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where {T} = _copyto_impl!(dest, doffs, src, soffs, n)
247,631,717✔
305

306
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
11✔
307
    n == 0 && return dest
155,364,536✔
308
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
117,928,551✔
309
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
117,929,088✔
310
    @boundscheck checkbounds(src, soffs:soffs+n-1)
117,929,049✔
311
    @inbounds let dest = GenericMemoryRef(dest isa Array ? getfield(dest, :ref) : dest, doffs)
117,929,043✔
312
                  src = GenericMemoryRef(src isa Array ? getfield(src, :ref) : src, soffs)
117,929,054✔
313
        unsafe_copyto!(dest, src, n)
235,858,048✔
314
    end
315
    return dest
117,928,802✔
316
end
317

318

319
# Outlining this because otherwise a catastrophic inference slowdown
320
# occurs, see discussion in #27874.
321
# It is also mitigated by using a constant string.
322
_throw_argerror(s) = (@noinline; throw(ArgumentError(s)))
10✔
323

324
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
35,753✔
325

326
# also to avoid ambiguities in packages
327
copyto!(dest::Array{T}, src::Array{T}) where {T} = copyto!(dest, 1, src, 1, length(src))
41,197,595✔
328

329
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
330
# for bootstrapping purposes.
331
function fill!(dest::Array{T}, x) where T
997✔
332
    xT = x isa T ? x : convert(T, x)::T
260,956✔
333
    for i in eachindex(dest)
942,975,230✔
334
        @inbounds dest[i] = xT
2,147,483,647✔
335
    end
2,147,483,647✔
336
    return dest
942,975,230✔
337
end
338

339
"""
340
    copy(x)
341

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

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

350
@eval function copy(a::Array{T}) where {T}
147,517✔
351
    # `jl_genericmemory_copy_slice` only throws when the size exceeds the max allocation
352
    # size, but since we're copying an existing array, we're guaranteed that this will not happen.
353
    @_nothrow_meta
282,596✔
354
    ref = a.ref
188,586,393✔
355
    newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a))
188,586,395✔
356
    return $(Expr(:new, :(typeof(a)), :(Core.memoryref(newmem)), :(a.size)))
188,586,278✔
357
end
358

359
## Constructors ##
360

361
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
236,536✔
362
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
7,745✔
363
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
16,608✔
364
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
24,366✔
365
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
4,589,673✔
366
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
90,317,722✔
367
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
641✔
368

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

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

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

384
julia> getindex(Int8, 1, 2, 3)
385
3-element Vector{Int8}:
386
 1
387
 2
388
 3
389
```
390
"""
391
function getindex(::Type{T}, vals...) where T
58,999✔
392
    @inline
154,818✔
393
    @_effect_free_terminates_locally_meta
154,818✔
394
    a = Vector{T}(undef, length(vals))
1,004,598,945✔
395
    if vals isa NTuple
154,850✔
396
        @_safeindex for i in 1:length(vals)
97,975✔
397
            a[i] = vals[i]
68,692,781✔
398
        end
239,939✔
399
    else
400
        # use afoldl to avoid type instability inside loop
401
        afoldl(1, vals...) do i, v
60,006✔
402
            @inbounds a[i] = v
127,000✔
403
            return i + 1
126,986✔
404
        end
405
    end
406
    return a
158,024✔
407
end
408

409
function getindex(::Type{Any}, @nospecialize vals...)
33,031,220✔
410
    @_effect_free_terminates_locally_meta
736✔
411
    a = Vector{Any}(undef, length(vals))
108,814,185✔
412
    @_safeindex for i = 1:length(vals)
41,568,124✔
413
        a[i] = vals[i]
151,305,965✔
414
    end
167,045,587✔
415
    return a
33,243,775✔
416
end
417
getindex(::Type{Any}) = Vector{Any}()
44,124,990✔
418

419
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
5✔
420
    ref = a.ref
11,471,105✔
421
    t = @_gc_preserve_begin ref
11,471,105✔
422
    p = unsafe_convert(Ptr{Cvoid}, ref)
11,471,105✔
423
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
11,471,108✔
424
    @_gc_preserve_end t
11,471,102✔
425
    return a
11,471,102✔
426
end
427

428
to_dim(d::Integer) = d
×
429
to_dim(d::OneTo) = last(d)
247✔
430

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

577
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
578
    @eval begin
579
        $fname(dims::DimOrInd...) = $fname(dims)
20,439,083✔
580
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
2,147,483,647✔
581
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,439,189✔
582
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,261✔
583
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
12,162✔
584
            a = Array{T,N}(undef, dims)
189,961,664✔
585
            fill!(a, $felt(T))
2,147,483,647✔
586
            return a
132,917,331✔
587
        end
588
        function $fname(::Type{T}, dims::Tuple{}) where {T}
589
            a = Array{T}(undef)
20✔
590
            fill!(a, $felt(T))
20✔
591
            return a
20✔
592
        end
593
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
×
594
            a = similar(Array{T,N}, dims)
×
595
            fill!(a, $felt(T))
×
596
            return a
×
597
        end
598
    end
599
end
600

601
function _one(unit::T, x::AbstractMatrix) where T
158✔
602
    require_one_based_indexing(x)
160✔
603
    m,n = size(x)
160✔
604
    m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
160✔
605
    # Matrix{T}(I, m, m)
606
    I = zeros(T, m, m)
3,771✔
607
    for i in 1:m
160✔
608
        I[i,i] = unit
653✔
609
    end
1,146✔
610
    I
160✔
611
end
612

613
one(x::AbstractMatrix{T}) where {T} = _one(one(T), x)
135✔
614
oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)
31✔
615

616
## Conversions ##
617

618
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
290,801✔
619

620
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
94✔
621

622
## Constructors ##
623

624
if nameof(@__MODULE__) === :Base  # avoid method overwrite
625
# constructors should make copies
626
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
295,993✔
627
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
9,932✔
628
end
629

630
## copying iterators to containers
631

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

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

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

649
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
39,991✔
650
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
651
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
27,712,295✔
652
    a = Vector{T}()
27,712,304✔
653
    for x in itr
47,647,737✔
654
        push!(a, x)
127,820,150✔
655
    end
235,704,866✔
656
    return a
27,712,304✔
657
end
658

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

662
_similar_shape(itr, ::SizeUnknown) = nothing
×
663
_similar_shape(itr, ::HasLength) = length(itr)::Integer
54,307,966✔
664
_similar_shape(itr, ::HasShape) = axes(itr)
647,735,438✔
665

666
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,289,164✔
667
    similar(c, T, 0)
668
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
14,614,205✔
669
    similar(c, T, len)
670
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
301,200✔
671
    similar(c, T, axs)
672

673
# make a collection appropriate for collecting `itr::Generator`
674
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
254✔
675
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
66,956,723✔
676
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
1,141,973,786✔
677

678
# used by syntax lowering for simple typed comprehensions
679
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
1,207,262,212✔
680

681

682
"""
683
    collect(collection)
684

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

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

694
# Examples
695

696
Collect items from a `UnitRange{Int64}` collection:
697

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

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

708
```jldoctest
709
julia> collect(x^2 for x in 1:3)
710
3-element Vector{Int64}:
711
 1
712
 4
713
 9
714
```
715
"""
716
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
16,118,427✔
717

718
collect(A::AbstractArray) = _collect_indices(axes(A), A)
135,917✔
719

720
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
190,438✔
721

722
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
14,601,294✔
723
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
724

725
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,288,950✔
726
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,289,004✔
727
    for x in itr
2,575,885✔
728
        push!(a,x)
10,355,709✔
729
    end
17,779,643✔
730
    return a
1,289,003✔
731
end
732

733
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
734
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
138,041✔
735
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
736
function _collect_indices(indsA, A)
27✔
737
    B = Array{eltype(A)}(undef, length.(indsA))
237✔
738
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
739
end
740

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

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

784
function collect(itr::Generator)
916,219✔
785
    isz = IteratorSize(itr.iter)
393,750✔
786
    et = @default_eltype(itr)
787
    if isa(isz, SizeUnknown)
393,750✔
788
        return grow_to!(Vector{et}(), itr)
97,034✔
789
    else
790
        shp = _similar_shape(itr, isz)
830,493✔
791
        y = iterate(itr)
1,641,675✔
792
        if y === nothing
829,866✔
793
            return _array_for(et, isz, shp)
7,710✔
794
        end
795
        v1, st = y
391,830✔
796
        dest = _array_for(typeof(v1), isz, shp)
1,632,482✔
797
        # The typeassert gives inference a helping hand on the element type and dimensionality
798
        # (work-around for #28382)
799
        et′ = et <: Type ? Type : et
391,830✔
800
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
391,943✔
801
        collect_to_with_first!(dest, v1, itr, st)::RT
10,812,160✔
802
    end
803
end
804

805
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
84✔
806
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
807

808
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
190,454✔
809
    et = @default_eltype(itr)
123,430✔
810
    shp = _similar_shape(itr, isz)
190,461✔
811
    y = iterate(itr)
378,827✔
812
    if y === nothing
190,459✔
813
        return _similar_for(c, et, itr, isz, shp)
2,068✔
814
    end
815
    v1, st = y
122,345✔
816
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
297,507✔
817
    # The typeassert gives inference a helping hand on the element type and dimensionality
818
    # (work-around for #28382)
819
    et′ = et <: Type ? Type : et
122,323✔
820
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
122,336✔
821
    collect_to_with_first!(dest, v1, itr, st)::RT
188,391✔
822
end
823

824
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
82,097✔
825
    i1 = first(LinearIndices(dest))
514,153✔
826
    dest[i1] = v1
1,010,547✔
827
    return collect_to!(dest, itr, i1+1, st)
12,093,827✔
828
end
829

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

835
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
227✔
836
    @inline
357✔
837
    new = similar(dest, promote_typejoin(T, typeof(el)))
802✔
838
    f = first(LinearIndices(dest))
357✔
839
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
799✔
840
    @inbounds new[i] = el
402✔
841
    return new
402✔
842
end
843

844
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
125,556✔
845
    # collect to dest array, checking the type of each result. if a result does not
846
    # match, widen the result type and re-dispatch.
847
    i = offs
514,510✔
848
    while true
91,681,627✔
849
        y = iterate(itr, st)
182,352,676✔
850
        y === nothing && break
91,681,617✔
851
        el, st = y
88,907,592✔
852
        if el isa T
88,920,011✔
853
            @inbounds dest[i] = el
90,670,678✔
854
            i += 1
90,670,678✔
855
        else
856
            new = setindex_widen_up_to(dest, el, i)
402✔
857
            return collect_to!(new, itr, i+1, st)
402✔
858
        end
859
    end
90,670,678✔
860
    return dest
1,010,537✔
861
end
862

863
function grow_to!(dest, itr)
1,193✔
864
    y = iterate(itr)
1,688✔
865
    y === nothing && return dest
1,361✔
866
    dest2 = empty(dest, typeof(y[1]))
436✔
867
    push!(dest2, y[1])
508✔
868
    grow_to!(dest2, itr, y[2])
415✔
869
end
870

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

884
function grow_to!(dest, itr, st)
411✔
885
    T = eltype(dest)
229✔
886
    y = iterate(itr, st)
679✔
887
    while y !== nothing
4,827✔
888
        el, st = y
3,064✔
889
        if el isa T
2,724✔
890
            push!(dest, el)
4,406✔
891
        else
892
            new = push_widen(dest, el)
13✔
893
            return grow_to!(new, itr, st)
10✔
894
        end
895
        y = iterate(itr, st)
6,556✔
896
    end
4,403✔
897
    return dest
414✔
898
end
899

900
## Iteration ##
901

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

904
## Indexing: getindex ##
905

906
"""
907
    getindex(collection, key...)
908

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

912
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
913

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

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

927
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
119,833✔
928
    @inline
176,114,840✔
929
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
185,593,323✔
930
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
185,593,691✔
931
end
932

933
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
934
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
9,765✔
935
    @inline
870,644✔
936
    @boundscheck checkbounds(A, I)
59,379,382✔
937
    lI = length(I)
59,379,391✔
938
    X = similar(A, axes(I))
89,283,898✔
939
    if lI > 0
59,379,380✔
940
        copyto!(X, firstindex(X), A, first(I), lI)
59,809,046✔
941
    end
942
    return X
59,379,380✔
943
end
944

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

948
function getindex(A::Array, c::Colon)
4,450✔
949
    lI = length(A)
2,289,676✔
950
    X = similar(A, lI)
4,579,350✔
951
    if lI > 0
2,289,676✔
952
        unsafe_copyto!(X, 1, A, 1, lI)
4,579,348✔
953
    end
954
    return X
2,289,676✔
955
end
956

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

962
## Indexing: setindex! ##
963

964
"""
965
    setindex!(collection, value, key...)
966

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

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

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

984
function setindex!(A::Array{T}, x, i::Int) where {T}
6,008,388✔
985
    @_noub_if_noinbounds_meta
701,250,765✔
986
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
2,147,483,647✔
987
    memoryrefset!(memoryref(A.ref, i, false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
2,147,483,647✔
988
    return A
2,147,483,647✔
989
end
990
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,484✔
991
    @inline
66,400,632✔
992
    @_noub_if_noinbounds_meta
66,400,632✔
993
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
68,687,258✔
994
    memoryrefset!(memoryref(A.ref, _to_linear_index(A, i1, i2, I...), false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
68,688,102✔
995
    return A
68,687,234✔
996
end
997

998
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
1,405,642✔
999
    memoryrefset!(memoryref(A.ref, i, false), x, :not_atomic, false); return A)
332,510,189✔
1000
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
435,825✔
1001
    memoryrefset!(memoryref(A.ref, i, false), x, :not_atomic, false); return A)
2,147,483,647✔
1002
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
1003
    __safe_setindex!(A, convert(T, x)::T, i))
36,108✔
1004

1005
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1006
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
91✔
1007
    @_propagate_inbounds_meta
816,727✔
1008
    @boundscheck setindex_shape_check(X, length(I))
9,496,606✔
1009
    @boundscheck checkbounds(A, I)
9,496,606✔
1010
    require_one_based_indexing(X)
816,727✔
1011
    X′ = unalias(A, X)
816,727✔
1012
    I′ = unalias(A, I)
816,727✔
1013
    count = 1
816,727✔
1014
    for i in I′
9,496,864✔
1015
        @inbounds A[i] = X′[count]
21,880,832✔
1016
        count += 1
21,880,826✔
1017
    end
35,701,260✔
1018
    return A
9,496,606✔
1019
end
1020

1021
# Faster contiguous setindex! with copyto!
1022
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
109✔
1023
    @inline
1,008,427✔
1024
    @boundscheck checkbounds(A, I)
1,008,662✔
1025
    lI = length(I)
1,008,662✔
1026
    @boundscheck setindex_shape_check(X, lI)
1,008,662✔
1027
    if lI > 0
1,008,662✔
1028
        unsafe_copyto!(A, first(I), X, 1, lI)
2,017,018✔
1029
    end
1030
    return A
1,008,662✔
1031
end
1032
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
40✔
1033
    @inline
74✔
1034
    lI = length(A)
74✔
1035
    @boundscheck setindex_shape_check(X, lI)
74✔
1036
    if lI > 0
74✔
1037
        unsafe_copyto!(A, 1, X, 1, lI)
148✔
1038
    end
1039
    return A
74✔
1040
end
1041

1042
# Pick new memory size for efficiently growing an array
1043
# TODO: This should know about the size of our GC pools
1044
# Specifically we are wasting ~10% of memory for small arrays
1045
# by not picking memory sizes that max out a GC pool
1046
function overallocation(maxsize)
1047
    maxsize < 8 && return 8;
1,257,293,054✔
1048
    # compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
1049
    # for small n, we grow faster than O(n)
1050
    # for large n, we grow at O(n/8)
1051
    # and as we reach O(memory) for memory>>1MB,
1052
    # this means we end by adding about 10% of memory each time
1053
    exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
90,836,010✔
1054
    maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8)
90,836,010✔
1055
    return maxsize
90,836,010✔
1056
end
1057

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

1060
function _growbeg!(a::Vector, delta::Integer)
38✔
1061
    @_noub_meta
19,057✔
1062
    delta = Int(delta)
19,057✔
1063
    delta == 0 && return # avoid attempting to index off the end
26,017,678✔
1064
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
26,017,106✔
1065
    ref = a.ref
72,737,237✔
1066
    mem = ref.mem
72,737,237✔
1067
    len = length(a)
72,737,237✔
1068
    offset = memoryrefoffset(ref)
72,737,237✔
1069
    newlen = len + delta
72,737,237✔
1070
    setfield!(a, :size, (newlen,))
72,737,237✔
1071
    # if offset is far enough advanced to fit data in existing memory without copying
1072
    if delta <= offset - 1
72,737,237✔
1073
        setfield!(a, :ref, @inbounds GenericMemoryRef(ref, 1 - delta))
45,803,356✔
1074
    else
1075
        @noinline (function()
53,867,814✔
1076
        memlen = length(mem)
26,933,934✔
1077
        if offset + len - 1 > memlen || offset < 1
53,867,868✔
1078
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1079
        end
1080
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1081
        # the +1 is because I didn't want to have an off by 1 error.
1082
        newmemlen = max(overallocation(memlen), len + 2 * delta + 1)
40,651,312✔
1083
        newoffset = div(newmemlen - newlen, 2) + 1
26,933,934✔
1084
        # If there is extra data after the end of the array we can use that space so long as there is enough
1085
        # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1086
        # Specifically, we want to ensure that we will only do this operation once before
1087
        # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1088
        if newoffset + newlen < memlen
26,933,934✔
1089
            newoffset = div(memlen - newlen, 2) + 1
×
1090
            newmem = mem
×
1091
        else
1092
            newmem = array_new_memory(mem, newmemlen)
26,933,934✔
1093
        end
1094
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
53,853,682✔
1095
        if ref !== a.ref
26,933,934✔
1096
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1097
        end
1098
        setfield!(a, :ref, @inbounds GenericMemoryRef(newmem, newoffset))
26,933,934✔
1099
        end)()
1100
    end
1101
    return
72,737,237✔
1102
end
1103

1104
function _growend!(a::Vector, delta::Integer)
28✔
1105
    @_noub_meta
7,745,712✔
1106
    delta = Int(delta)
7,764,569✔
1107
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,199,320,242✔
1108
    ref = a.ref
2,147,483,647✔
1109
    mem = ref.mem
2,147,483,647✔
1110
    memlen = length(mem)
2,147,483,647✔
1111
    len = length(a)
2,147,483,647✔
1112
    newlen = len + delta
2,147,483,647✔
1113
    offset = memoryrefoffset(ref)
2,147,483,647✔
1114
    setfield!(a, :size, (newlen,))
2,147,483,647✔
1115
    newmemlen = offset + newlen - 1
2,147,483,647✔
1116
    if memlen < newmemlen
2,147,483,647✔
1117
        @noinline (function()
2,147,483,647✔
1118
        if offset + len - 1 > memlen || offset < 1
2,147,483,647✔
1119
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1120
        end
1121

1122
        if offset - 1 > div(5 * newlen, 4)
1,208,580,578✔
1123
            # If the offset is far enough that we can copy without resizing
1124
            # while maintaining proportional spacing on both ends of the array
1125
            # note that this branch prevents infinite growth when doing combinations
1126
            # of push! and popfirst! (i.e. when using a Vector as a queue)
1127
            newmem = mem
23,148✔
1128
            newoffset = div(newlen, 8) + 1
23,148✔
1129
        else
1130
            # grow either by our computed overallocation factor
1131
            # or exactly the requested size, whichever is larger
1132
            # TODO we should possibly increase the offset if the current offset is nonzero.
1133
            newmemlen2 = max(overallocation(memlen), newmemlen)
1,277,300,541✔
1134
            newmem = array_new_memory(mem, newmemlen2)
2,147,483,647✔
1135
            newoffset = offset
1,208,557,430✔
1136
        end
1137
        newref = @inbounds GenericMemoryRef(newmem, newoffset)
1,208,580,578✔
1138
        unsafe_copyto!(newref, ref, len)
1,317,823,531✔
1139
        if ref !== a.ref
1,208,580,578✔
1140
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1141
        end
1142
        setfield!(a, :ref, newref)
1,208,580,578✔
1143
        end)()
1144
    end
1145
    return
2,147,483,647✔
1146
end
1147

1148
function _growat!(a::Vector, i::Integer, delta::Integer)
108,921,469✔
1149
    @_terminates_globally_noub_meta
287,883✔
1150
    delta = Int(delta)
287,883✔
1151
    i = Int(i)
287,883✔
1152
    i == 1 && return _growbeg!(a, delta)
108,921,469✔
1153
    len = length(a)
83,361,874✔
1154
    i == len + 1 && return _growend!(a, delta)
83,361,874✔
1155
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
83,294,771✔
1156
    1 < i <= len || throw(BoundsError(a, i))
83,294,773✔
1157
    ref = a.ref
83,294,769✔
1158
    mem = ref.mem
83,294,769✔
1159
    memlen = length(mem)
83,294,769✔
1160
    newlen = len + delta
83,294,769✔
1161
    offset = memoryrefoffset(ref)
83,294,769✔
1162
    setfield!(a, :size, (newlen,))
83,294,769✔
1163
    newmemlen = offset + newlen - 1
83,294,769✔
1164

1165
    # which side would we rather grow into?
1166
    prefer_start = i <= div(len, 2)
83,294,769✔
1167
    # if offset is far enough advanced to fit data in beginning of the memory
1168
    if prefer_start && delta <= offset - 1
83,294,769✔
1169
        newref = @inbounds GenericMemoryRef(mem, offset - delta)
33,802,424✔
1170
        unsafe_copyto!(newref, ref, i)
67,604,848✔
1171
        setfield!(a, :ref, newref)
33,802,424✔
1172
        for j in i:i+delta-1
33,802,424✔
1173
            @inbounds _unsetindex!(a, j)
47,702,515✔
1174
        end
47,695,646✔
1175
    elseif !prefer_start && memlen >= newmemlen
49,492,345✔
1176
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
70,760,442✔
1177
        for j in i:i+delta-1
35,380,221✔
1178
            @inbounds _unsetindex!(a, j)
49,073,143✔
1179
        end
49,064,015✔
1180
    else
1181
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1182
        # the +1 is because I didn't want to have an off by 1 error.
1183
        newmemlen = max(overallocation(memlen), len+2*delta+1)
20,516,720✔
1184
        newoffset = (newmemlen - newlen) ÷ 2 + 1
14,112,124✔
1185
        newmem = array_new_memory(mem, newmemlen)
28,224,248✔
1186
        newref = @inbounds GenericMemoryRef(newmem, newoffset)
14,112,124✔
1187
        unsafe_copyto!(newref, ref, i-1)
28,224,248✔
1188
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
28,224,248✔
1189
        setfield!(a, :ref, newref)
14,112,124✔
1190
    end
1191
end
1192

1193
# efficiently delete part of an array
1194
function _deletebeg!(a::Vector, delta::Integer)
21,020,433✔
1195
    delta = Int(delta)
1,083,440✔
1196
    len = length(a)
74,001,146✔
1197
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
74,001,146✔
1198
    for i in 1:delta
22,206,021✔
1199
        @inbounds _unsetindex!(a, i)
101,017,609✔
1200
    end
34,119,291✔
1201
    newlen = len - delta
74,001,146✔
1202
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
74,001,146✔
1203
        newref = @inbounds GenericMemoryRef(a.ref, delta + 1)
66,611,334✔
1204
        setfield!(a, :ref, newref)
66,611,334✔
1205
    end
1206
    setfield!(a, :size, (newlen,))
74,001,146✔
1207
    return
74,001,146✔
1208
end
1209
function _deleteend!(a::Vector, delta::Integer)
23,140,002✔
1210
    delta = Int(delta)
4,505,372✔
1211
    len = length(a)
1,531,293,187✔
1212
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
1,531,293,187✔
1213
    newlen = len - delta
1,531,293,187✔
1214
    for i in newlen+1:len
1,585,708,034✔
1215
        @inbounds _unsetindex!(a, i)
2,147,483,647✔
1216
    end
2,147,483,647✔
1217
    setfield!(a, :size, (newlen,))
1,531,293,187✔
1218
    return
1,531,293,187✔
1219
end
1220
function _deleteat!(a::Vector, i::Integer, delta::Integer)
7,701,619✔
1221
    i = Int(i)
102,110✔
1222
    len = length(a)
7,701,619✔
1223
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
7,701,619✔
1224
    1 <= i <= len || throw(BoundsError(a, i))
7,701,622✔
1225
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
7,701,616✔
1226
    newa = a
102,095✔
1227
    if 2*i + delta <= len
7,701,616✔
1228
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
170,748✔
1229
        _deletebeg!(a, delta)
3,541,971✔
1230
    else
1231
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
10,231,276✔
1232
        _deleteend!(a, delta)
7,576,516✔
1233
    end
1234
    return
7,701,616✔
1235
end
1236
## Dequeue functionality ##
1237

1238
"""
1239
    push!(collection, items...) -> collection
1240

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

1244
# Examples
1245
```jldoctest
1246
julia> push!([1, 2, 3], 4, 5, 6)
1247
6-element Vector{Int64}:
1248
 1
1249
 2
1250
 3
1251
 4
1252
 5
1253
 6
1254
```
1255

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

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

1262
See also [`pushfirst!`](@ref).
1263
"""
1264
function push! end
1265

1266
function push!(a::Vector{T}, item) where T
62,940✔
1267
    # convert first so we don't grow the array if the assignment won't work
1268
    itemT = item isa T ? item : convert(T, item)::T
41,655,654✔
1269
    _growend!(a, 1)
2,147,483,647✔
1270
    @_safeindex a[length(a)] = itemT
2,147,483,647✔
1271
    return a
2,147,483,647✔
1272
end
1273

1274
# specialize and optimize the single argument case
1275
function push!(a::Vector{Any}, @nospecialize x)
6,995✔
1276
    _growend!(a, 1)
134,251,384✔
1277
    @_safeindex a[length(a)] = x
134,251,384✔
1278
    return a
134,251,384✔
1279
end
1280
function push!(a::Vector{Any}, @nospecialize x...)
16✔
1281
    @_terminates_locally_meta
17✔
1282
    na = length(a)
267,102✔
1283
    nx = length(x)
17✔
1284
    _growend!(a, nx)
267,102✔
1285
    @_safeindex for i = 1:nx
534,187✔
1286
        a[na+i] = x[i]
684,835✔
1287
    end
801,420✔
1288
    return a
267,102✔
1289
end
1290

1291
"""
1292
    append!(collection, collections...) -> collection.
1293

1294
For an ordered container `collection`, add the elements of each `collections`
1295
to the end of it.
1296

1297
!!! compat "Julia 1.6"
1298
    Specifying multiple collections to be appended requires at least Julia 1.6.
1299

1300
# Examples
1301
```jldoctest
1302
julia> append!([1], [2, 3])
1303
3-element Vector{Int64}:
1304
 1
1305
 2
1306
 3
1307

1308
julia> append!([1, 2, 3], [4, 5], [6])
1309
6-element Vector{Int64}:
1310
 1
1311
 2
1312
 3
1313
 4
1314
 5
1315
 6
1316
```
1317

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

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

1324
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1325
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1326
"""
1327
function append! end
1328

1329
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
8,394✔
1330
    items isa Tuple && (items = map(x -> convert(T, x), items))
2,251,598✔
1331
    n = length(items)
83,446,792✔
1332
    _growend!(a, n)
83,999,601✔
1333
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
129,273,805✔
1334
    return a
83,999,601✔
1335
end
1336

1337
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
85,410,195✔
1338
push!(a::AbstractVector, iter...) = append!(a, iter)
1,292,095✔
1339

1340
append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
7✔
1341

1342
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
26,810,713✔
1343
    n = Int(length(iter))::Int
27,043,871✔
1344
    i = lastindex(a)
30✔
1345
    sizehint!(a, length(a) + n; shrink=false)
26,810,715✔
1346
    for item in iter
43,635,164✔
1347
        push!(a, item)
50,306,958✔
1348
    end
50,538,352✔
1349
    a
11✔
1350
end
1351
function _append!(a::AbstractVector, ::IteratorSize, iter)
58,599,479✔
1352
    for item in iter
71,156,503✔
1353
        push!(a, item)
59,725,545✔
1354
    end
59,725,550✔
1355
    a
3✔
1356
end
1357

1358
"""
1359
    prepend!(a::Vector, collections...) -> collection
1360

1361
Insert the elements of each `collections` to the beginning of `a`.
1362

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

1366
!!! compat "Julia 1.6"
1367
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1368

1369
# Examples
1370
```jldoctest
1371
julia> prepend!([3], [1, 2])
1372
3-element Vector{Int64}:
1373
 1
1374
 2
1375
 3
1376

1377
julia> prepend!([6], [1, 2], [3, 4, 5])
1378
6-element Vector{Int64}:
1379
 1
1380
 2
1381
 3
1382
 4
1383
 5
1384
 6
1385
```
1386
"""
1387
function prepend! end
1388

1389
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
2,151✔
1390
    items isa Tuple && (items = map(x -> convert(T, x), items))
4,904✔
1391
    n = length(items)
6,837✔
1392
    _growbeg!(a, n)
13,101✔
1393
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1394
    # just the last n elements instead of all of them from the first
1395
    copyto!(a, 1, items, lastindex(items)-n+1, n)
13,096✔
1396
    return a
6,837✔
1397
end
1398

1399
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
356✔
1400
pushfirst!(a::Vector, iter...) = prepend!(a, iter)
7✔
1401

1402
prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
101,541✔
1403

1404
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
352✔
1405
    @_terminates_locally_meta
353✔
1406
    require_one_based_indexing(a)
353✔
1407
    n = Int(length(iter))::Int
353✔
1408
    sizehint!(a, length(a) + n; first=true, shrink=false)
353✔
1409
    n = 0
353✔
1410
    for item in iter
354✔
1411
        n += 1
585✔
1412
        pushfirst!(a, item)
585✔
1413
    end
581✔
1414
    reverse!(a, 1, n)
347✔
1415
    a
347✔
1416
end
1417
function _prepend!(a::Vector, ::IteratorSize, iter)
3✔
1418
    n = 0
3✔
1419
    for item in iter
5✔
1420
        n += 1
8✔
1421
        pushfirst!(a, item)
11✔
1422
    end
13✔
1423
    reverse!(a, 1, n)
2✔
1424
    a
2✔
1425
end
1426

1427
"""
1428
    resize!(a::Vector, n::Integer) -> Vector
1429

1430
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1431
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1432
guaranteed to be initialized.
1433

1434
# Examples
1435
```jldoctest
1436
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1437
3-element Vector{Int64}:
1438
 6
1439
 5
1440
 4
1441

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

1444
julia> length(a)
1445
8
1446

1447
julia> a[1:6]
1448
6-element Vector{Int64}:
1449
 6
1450
 5
1451
 4
1452
 3
1453
 2
1454
 1
1455
```
1456
"""
1457
function resize!(a::Vector, nl::Integer)
1,307,938,454✔
1458
    l = length(a)
1,370,108,752✔
1459
    if nl > l
1,370,108,752✔
1460
        _growend!(a, nl-l)
904,814,553✔
1461
    elseif nl != l
465,294,201✔
1462
        if nl < 0
116,568,746✔
1463
            _throw_argerror("new length must be ≥ 0")
2✔
1464
        end
1465
        _deleteend!(a, l-nl)
116,568,744✔
1466
    end
1467
    return a
1,370,108,750✔
1468
end
1469

1470
"""
1471
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1472

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

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

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

1486
See also [`resize!`](@ref).
1487

1488
# Notes on the performance model
1489

1490
For types that support `sizehint!`,
1491

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

1496
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1497
   `Base`.
1498

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

1501
!!! compat "Julia 1.11"
1502
    The `shrink` and `first` arguments were added in Julia 1.11.
1503
"""
1504
function sizehint! end
1505

1506
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
53,920,062✔
1507
    len = length(a)
26,959,275✔
1508
    ref = a.ref
26,959,275✔
1509
    mem = ref.mem
26,959,275✔
1510
    memlen = length(mem)
26,959,275✔
1511
    sz = max(Int(sz), len)
26,959,275✔
1512
    inc = sz - len
26,959,275✔
1513
    if sz <= memlen
26,959,275✔
1514
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1515
        if !shrink || memlen - sz <= div(memlen, 8)
23,445,245✔
1516
            return a
23,196,055✔
1517
        end
1518
        newmem = array_new_memory(mem, sz)
141,724✔
1519
        if first
116,209✔
1520
            newref = GenericMemoryRef(newmem, inc + 1)
×
1521
        else
1522
            newref = GenericMemoryRef(newmem)
116,209✔
1523
        end
1524
        unsafe_copyto!(newref, ref, len)
160,663✔
1525
        setfield!(a, :ref, newref)
116,209✔
1526
    elseif first
3,647,011✔
1527
        _growbeg!(a, inc)
694✔
1528
        newref = getfield(a, :ref)
347✔
1529
        newref = GenericMemoryRef(newref, inc + 1)
347✔
1530
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
347✔
1531
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
347✔
1532
    else # last
1533
        _growend!(a, inc)
3,646,664✔
1534
        setfield!(a, :size, (len,)) # undo the size change from _growend!
3,646,664✔
1535
    end
1536
    a
6,799✔
1537
end
1538

1539
# Fall-back implementation for non-shrinkable collections
1540
# avoid defining this the normal way to avoid avoid infinite recursion
1541
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
10✔
1542
    get(kwargs, :first, false)::Bool
211✔
1543
    get(kwargs, :shrink, true)::Bool
211✔
1544
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
211✔
1545
    sizehint!(a, sz)
211✔
1546
end
1547

1548
"""
1549
    pop!(collection) -> item
1550

1551
Remove an item in `collection` and return it. If `collection` is an
1552
ordered container, the last item is returned; for unordered containers,
1553
an arbitrary element is returned.
1554

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

1557
# Examples
1558
```jldoctest
1559
julia> A=[1, 2, 3]
1560
3-element Vector{Int64}:
1561
 1
1562
 2
1563
 3
1564

1565
julia> pop!(A)
1566
3
1567

1568
julia> A
1569
2-element Vector{Int64}:
1570
 1
1571
 2
1572

1573
julia> S = Set([1, 2])
1574
Set{Int64} with 2 elements:
1575
  2
1576
  1
1577

1578
julia> pop!(S)
1579
2
1580

1581
julia> S
1582
Set{Int64} with 1 element:
1583
  1
1584

1585
julia> pop!(Dict(1=>2))
1586
1 => 2
1587
```
1588
"""
1589
function pop!(a::Vector)
23,212✔
1590
    if isempty(a)
1,307,483,913✔
1591
        _throw_argerror("array must be non-empty")
1✔
1592
    end
1593
    item = a[end]
1,307,483,912✔
1594
    _deleteend!(a, 1)
1,307,483,912✔
1595
    return item
1,307,483,912✔
1596
end
1597

1598
"""
1599
    popat!(a::Vector, i::Integer, [default])
1600

1601
Remove the item at the given `i` and return it. Subsequent items
1602
are shifted to fill the resulting gap.
1603
When `i` is not a valid index for `a`, return `default`, or throw an error if
1604
`default` is not specified.
1605

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

1608
!!! compat "Julia 1.5"
1609
    This function is available as of Julia 1.5.
1610

1611
# Examples
1612
```jldoctest
1613
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1614
3
1615

1616
julia> a
1617
3-element Vector{Int64}:
1618
 4
1619
 2
1620
 1
1621

1622
julia> popat!(a, 4, missing)
1623
missing
1624

1625
julia> popat!(a, 4)
1626
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1627
[...]
1628
```
1629
"""
1630
function popat!(a::Vector, i::Integer)
4✔
1631
    x = a[i]
10✔
1632
    _deleteat!(a, i, 1)
4✔
1633
    x
4✔
1634
end
1635

1636
function popat!(a::Vector, i::Integer, default)
2✔
1637
    if 1 <= i <= length(a)
2✔
1638
        x = @inbounds a[i]
1✔
1639
        _deleteat!(a, i, 1)
1✔
1640
        x
1✔
1641
    else
1642
        default
1✔
1643
    end
1644
end
1645

1646
"""
1647
    pushfirst!(collection, items...) -> collection
1648

1649
Insert one or more `items` at the beginning of `collection`.
1650

1651
This function is called `unshift` in many other programming languages.
1652

1653
# Examples
1654
```jldoctest
1655
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1656
6-element Vector{Int64}:
1657
 5
1658
 6
1659
 1
1660
 2
1661
 3
1662
 4
1663
```
1664
"""
1665
function pushfirst!(a::Vector{T}, item) where T
409✔
1666
    item = item isa T ? item : convert(T, item)::T
2,846✔
1667
    _growbeg!(a, 1)
38,995✔
1668
    @_safeindex a[1] = item
37,199✔
1669
    return a
37,199✔
1670
end
1671

1672
# specialize and optimize the single argument case
1673
function pushfirst!(a::Vector{Any}, @nospecialize x)
13✔
1674
    _growbeg!(a, 1)
47,666,244✔
1675
    @_safeindex a[1] = x
46,684,352✔
1676
    return a
46,684,352✔
1677
end
1678
function pushfirst!(a::Vector{Any}, @nospecialize x...)
1✔
1679
    @_terminates_locally_meta
2✔
1680
    na = length(a)
2✔
1681
    nx = length(x)
2✔
1682
    _growbeg!(a, nx)
1,346✔
1683
    @_safeindex for i = 1:nx
1,344✔
1684
        a[i] = x[i]
1,348✔
1685
    end
2,023✔
1686
    return a
673✔
1687
end
1688

1689
"""
1690
    popfirst!(collection) -> item
1691

1692
Remove the first `item` from `collection`.
1693

1694
This function is called `shift` in many other programming languages.
1695

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

1698
# Examples
1699
```jldoctest
1700
julia> A = [1, 2, 3, 4, 5, 6]
1701
6-element Vector{Int64}:
1702
 1
1703
 2
1704
 3
1705
 4
1706
 5
1707
 6
1708

1709
julia> popfirst!(A)
1710
1
1711

1712
julia> A
1713
5-element Vector{Int64}:
1714
 2
1715
 3
1716
 4
1717
 5
1718
 6
1719
```
1720
"""
1721
function popfirst!(a::Vector)
321✔
1722
    if isempty(a)
73,848,992✔
1723
        _throw_argerror("array must be non-empty")
1✔
1724
    end
1725
    item = a[1]
73,848,991✔
1726
    _deletebeg!(a, 1)
73,848,991✔
1727
    return item
73,848,991✔
1728
end
1729

1730
"""
1731
    insert!(a::Vector, index::Integer, item)
1732

1733
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1734
the resulting `a`.
1735

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

1738
# Examples
1739
```jldoctest
1740
julia> insert!(Any[1:6;], 3, "here")
1741
7-element Vector{Any}:
1742
 1
1743
 2
1744
  "here"
1745
 3
1746
 4
1747
 5
1748
 6
1749
```
1750
"""
1751
function insert!(a::Array{T,1}, i::Integer, item) where T
299✔
1752
    @_noub_meta
1,360,999✔
1753
    # Throw convert error before changing the shape of the array
1754
    _item = item isa T ? item : convert(T, item)::T
1,361,003✔
1755
    _growat!(a, i, 1)
87,404,427✔
1756
    # :noub, because _growat! already did bound check
1757
    @inbounds a[i] = _item
87,404,425✔
1758
    return a
87,404,425✔
1759
end
1760

1761
"""
1762
    deleteat!(a::Vector, i::Integer)
1763

1764
Remove the item at the given `i` and return the modified `a`. Subsequent items
1765
are shifted to fill the resulting gap.
1766

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

1769
# Examples
1770
```jldoctest
1771
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1772
5-element Vector{Int64}:
1773
 6
1774
 4
1775
 3
1776
 2
1777
 1
1778
```
1779
"""
1780
function deleteat!(a::Vector, i::Integer)
404✔
1781
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,833✔
1782
    _deleteat!(a, i, 1)
7,497,713✔
1783
    return a
16,831✔
1784
end
1785

1786
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
34,081✔
1787
    if eltype(r) === Bool
75,700✔
1788
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1789
    else
1790
        n = length(a)
75,694✔
1791
        f = first(r)
75,694✔
1792
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
75,694✔
1793
        isempty(r) || _deleteat!(a, f, length(r))
384,934✔
1794
        return a
194,292✔
1795
    end
1796
end
1797

1798
"""
1799
    deleteat!(a::Vector, inds)
1800

1801
Remove the items at the indices given by `inds`, and return the modified `a`.
1802
Subsequent items are shifted to fill the resulting gap.
1803

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

1807
# Examples
1808
```jldoctest
1809
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1810
3-element Vector{Int64}:
1811
 5
1812
 3
1813
 1
1814

1815
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1816
3-element Vector{Int64}:
1817
 5
1818
 3
1819
 1
1820

1821
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1822
ERROR: ArgumentError: indices must be unique and sorted
1823
Stacktrace:
1824
[...]
1825
```
1826
"""
1827
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1828
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
105,251✔
1829

1830
struct Nowhere; end
1831
push!(::Nowhere, _) = nothing
×
1832
_growend!(::Nowhere, _) = nothing
×
1833

1834
function _push_deleted!(dltd, a::Vector, ind)
1835
    @_propagate_inbounds_meta
1,492,759✔
1836
    if isassigned(a, ind)
1,569,589✔
1837
        push!(dltd, a[ind])
1,569,588✔
1838
    else
1839
        _growend!(dltd, 1)
×
1840
    end
1841
end
1842

1843
function _copy_item!(a::Vector, p, q)
1844
    @_propagate_inbounds_meta
4,376,912✔
1845
    if isassigned(a, q)
4,416,219✔
1846
        a[p] = a[q]
4,416,218✔
1847
    else
1848
        _unsetindex!(a, p)
1✔
1849
    end
1850
end
1851

1852
function _deleteat!(a::Vector, inds, dltd=Nowhere())
105,271✔
1853
    n = length(a)
210,541✔
1854
    y = iterate(inds)
105,281✔
1855
    y === nothing && return a
105,271✔
1856
    (p, s) = y
35,472✔
1857
    checkbounds(a, p)
105,040✔
1858
    @inbounds _push_deleted!(dltd, a, p)
105,028✔
1859
    q = p+1
105,028✔
1860
    while true
1,569,589✔
1861
        y = iterate(inds, s)
1,569,600✔
1862
        y === nothing && break
1,569,589✔
1863
        (i,s) = y
1,457,293✔
1864
        if !(q <= i <= n)
1,464,563✔
1865
            if i < q
2✔
1866
                _throw_argerror("indices must be unique and sorted")
1✔
1867
            else
1868
                throw(BoundsError())
1✔
1869
            end
1870
        end
1871
        while q < i
2,889,154✔
1872
            @inbounds _copy_item!(a, p, q)
1,424,593✔
1873
            p += 1; q += 1
1,424,593✔
1874
        end
1,424,593✔
1875
        @inbounds _push_deleted!(dltd, a, i)
1,464,561✔
1876
        q = i+1
1,464,561✔
1877
    end
1,464,561✔
1878
    while q <= n
3,054,458✔
1879
        @inbounds _copy_item!(a, p, q)
2,949,432✔
1880
        p += 1; q += 1
2,949,432✔
1881
    end
2,949,432✔
1882
    _deleteend!(a, n-p+1)
1,569,587✔
1883
    return a
105,026✔
1884
end
1885

1886
# Simpler and more efficient version for logical indexing
1887
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1888
    n = length(a)
4,029✔
1889
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1890
    p = 1
4,024✔
1891
    for (q, i) in enumerate(inds)
8,047✔
1892
        @inbounds _copy_item!(a, p, q)
42,194✔
1893
        p += !i
42,194✔
1894
    end
80,365✔
1895
    _deleteend!(a, n-p+1)
21,353✔
1896
    return a
4,024✔
1897
end
1898

1899
const _default_splice = []
1900

1901
"""
1902
    splice!(a::Vector, index::Integer, [replacement]) -> item
1903

1904
Remove the item at the given index, and return the removed item.
1905
Subsequent items are shifted left to fill the resulting gap.
1906
If specified, replacement values from an ordered
1907
collection will be spliced in place of the removed item.
1908

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

1911
# Examples
1912
```jldoctest
1913
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1914
2
1915

1916
julia> A
1917
5-element Vector{Int64}:
1918
 6
1919
 5
1920
 4
1921
 3
1922
 1
1923

1924
julia> splice!(A, 5, -1)
1925
1
1926

1927
julia> A
1928
5-element Vector{Int64}:
1929
  6
1930
  5
1931
  4
1932
  3
1933
 -1
1934

1935
julia> splice!(A, 1, [-1, -2, -3])
1936
6
1937

1938
julia> A
1939
7-element Vector{Int64}:
1940
 -1
1941
 -2
1942
 -3
1943
  5
1944
  4
1945
  3
1946
 -1
1947
```
1948

1949
To insert `replacement` before an index `n` without removing any items, use
1950
`splice!(collection, n:n-1, replacement)`.
1951
"""
1952
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,695✔
1953
    v = a[i]
3,712✔
1954
    m = length(ins)
3,426✔
1955
    if m == 0
3,426✔
1956
        _deleteat!(a, i, 1)
551✔
1957
    elseif m == 1
2,875✔
1958
        a[i] = only(ins)
266✔
1959
    else
1960
        _growat!(a, i, m-1)
2,609✔
1961
        k = 1
2,609✔
1962
        for x in ins
2,609✔
1963
            a[i+k-1] = x
334,327✔
1964
            k += 1
334,327✔
1965
        end
334,327✔
1966
    end
1967
    return v
3,426✔
1968
end
1969

1970
"""
1971
    splice!(a::Vector, indices, [replacement]) -> items
1972

1973
Remove items at specified indices, and return a collection containing
1974
the removed items.
1975
Subsequent items are shifted left to fill the resulting gaps.
1976
If specified, replacement values from an ordered collection will be spliced in
1977
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
1978

1979
To insert `replacement` before an index `n` without removing any items, use
1980
`splice!(collection, n:n-1, replacement)`.
1981

1982
$(_DOCS_ALIASING_WARNING)
1983

1984
!!! compat "Julia 1.5"
1985
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1986

1987
!!! compat "Julia 1.8"
1988
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1989

1990
# Examples
1991
```jldoctest
1992
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
1993
Int64[]
1994

1995
julia> A
1996
8-element Vector{Int64}:
1997
 -1
1998
 -2
1999
 -3
2000
  2
2001
  5
2002
  4
2003
  3
2004
 -1
2005
```
2006
"""
2007
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
21,598,243✔
2008
    v = a[r]
21,668,473✔
2009
    m = length(ins)
71,650✔
2010
    if m == 0
71,650✔
2011
        deleteat!(a, r)
74,059✔
2012
        return v
37,090✔
2013
    end
2014

2015
    n = length(a)
21,527,215✔
2016
    f = first(r)
21,527,215✔
2017
    l = last(r)
21,527,215✔
2018
    d = length(r)
21,527,215✔
2019

2020
    if m < d
21,527,215✔
2021
        delta = d - m
12,675✔
2022
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
19,122✔
2023
    elseif m > d
21,514,540✔
2024
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
21,514,413✔
2025
    end
2026

2027
    k = 1
34,560✔
2028
    for x in ins
21,538,721✔
2029
        a[f+k-1] = x
69,862,231✔
2030
        k += 1
68,516,998✔
2031
    end
91,355,960✔
2032
    return v
21,527,215✔
2033
end
2034

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

2037
function empty!(a::Vector)
51✔
2038
    _deleteend!(a, length(a))
111,889,854✔
2039
    return a
99,490,578✔
2040
end
2041

2042
# use memcmp for cmp on byte arrays
2043
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
2044
    aref = a.ref
3✔
2045
    bref = b.ref
3✔
2046
    ta = @_gc_preserve_begin aref
3✔
2047
    tb = @_gc_preserve_begin bref
3✔
2048
    pa = unsafe_convert(Ptr{Cvoid}, aref)
3✔
2049
    pb = unsafe_convert(Ptr{Cvoid}, bref)
3✔
2050
    c = memcmp(pa, pb, min(length(a),length(b)))
3✔
2051
    @_gc_preserve_end ta
3✔
2052
    @_gc_preserve_end tb
3✔
2053
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
2054
end
2055

2056
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2057
# use memcmp for == on bit integer types
2058
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,459✔
2059
    if size(a) == size(b)
3,561✔
2060
        aref = a.ref
1,811✔
2061
        bref = b.ref
1,811✔
2062
        ta = @_gc_preserve_begin aref
1,811✔
2063
        tb = @_gc_preserve_begin bref
1,811✔
2064
        pa = unsafe_convert(Ptr{Cvoid}, aref)
1,811✔
2065
        pb = unsafe_convert(Ptr{Cvoid}, bref)
1,811✔
2066
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
1,811✔
2067
        @_gc_preserve_end ta
1,811✔
2068
        @_gc_preserve_end tb
1,811✔
2069
        return c == 0
1,811✔
2070
    else
2071
        return false
×
2072
    end
2073
end
2074

2075
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
5,569✔
2076
    len = length(a)
58,808✔
2077
    if len == length(b)
58,808✔
2078
        aref = a.ref
58,684✔
2079
        bref = b.ref
25,788✔
2080
        ta = @_gc_preserve_begin aref
58,684✔
2081
        tb = @_gc_preserve_begin bref
58,684✔
2082
        T = eltype(Arr)
13,718✔
2083
        pa = unsafe_convert(Ptr{T}, aref)
58,684✔
2084
        pb = unsafe_convert(Ptr{T}, bref)
58,684✔
2085
        c = memcmp(pa, pb, sizeof(T) * len)
58,684✔
2086
        @_gc_preserve_end ta
58,684✔
2087
        @_gc_preserve_end tb
58,684✔
2088
        return c == 0
58,684✔
2089
    else
2090
        return false
124✔
2091
    end
2092
end
2093

2094
"""
2095
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2096

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

2100
# Examples
2101
```jldoctest
2102
julia> A = Vector(1:5)
2103
5-element Vector{Int64}:
2104
 1
2105
 2
2106
 3
2107
 4
2108
 5
2109

2110
julia> reverse(A)
2111
5-element Vector{Int64}:
2112
 5
2113
 4
2114
 3
2115
 2
2116
 1
2117

2118
julia> reverse(A, 1, 4)
2119
5-element Vector{Int64}:
2120
 4
2121
 3
2122
 2
2123
 1
2124
 5
2125

2126
julia> reverse(A, 3, 5)
2127
5-element Vector{Int64}:
2128
 1
2129
 2
2130
 5
2131
 4
2132
 3
2133
```
2134
"""
2135
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
8,980✔
2136
    s, n = Int(start), Int(stop)
916✔
2137
    B = similar(A)
17,690✔
2138
    for i = firstindex(A):s-1
8,981✔
2139
        B[i] = A[i]
1,684✔
2140
    end
3,078✔
2141
    for i = s:n
8,990✔
2142
        B[i] = A[n+s-i]
290,248✔
2143
    end
571,526✔
2144
    for i = n+1:lastindex(A)
17,670✔
2145
        B[i] = A[i]
1,690✔
2146
    end
3,090✔
2147
    return B
8,980✔
2148
end
2149

2150
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2151
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2152
    @eval begin
2153
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
166,159,336✔
2154
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
12,992✔
2155
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2156
        function $_f(A::AbstractVector, dim::Integer)
2157
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
2158
            return $_f(A, :)
4✔
2159
        end
2160
    end
2161
end
2162

2163
function reverseind(a::AbstractVector, i::Integer)
3✔
2164
    li = LinearIndices(a)
3✔
2165
    first(li) + last(li) - i
3✔
2166
end
2167

2168
# This implementation of `midpoint` is performance-optimized but safe
2169
# only if `lo <= hi`.
2170
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
17,518,698✔
2171
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2172

2173
"""
2174
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2175

2176
In-place version of [`reverse`](@ref).
2177

2178
# Examples
2179
```jldoctest
2180
julia> A = Vector(1:5)
2181
5-element Vector{Int64}:
2182
 1
2183
 2
2184
 3
2185
 4
2186
 5
2187

2188
julia> reverse!(A);
2189

2190
julia> A
2191
5-element Vector{Int64}:
2192
 5
2193
 4
2194
 3
2195
 2
2196
 1
2197
```
2198
"""
2199
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
180,364✔
2200
    s, n = Int(start), Int(stop)
42,702✔
2201
    if n > s # non-empty and non-trivial
180,361✔
2202
        liv = LinearIndices(v)
171,424✔
2203
        if !(first(liv) ≤ s ≤ last(liv))
171,424✔
2204
            throw(BoundsError(v, s))
3✔
2205
        elseif !(first(liv) ≤ n ≤ last(liv))
171,421✔
2206
            throw(BoundsError(v, n))
1✔
2207
        end
2208
        r = n
39,357✔
2209
        @inbounds for i in s:midpoint(s, n-1)
171,420✔
2210
            v[i], v[r] = v[r], v[i]
9,930,170✔
2211
            r -= 1
9,930,170✔
2212
        end
19,688,920✔
2213
    end
2214
    return v
180,357✔
2215
end
2216

2217
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2218

2219
vcat() = Vector{Any}()
9,776✔
2220
hcat() = Vector{Any}()
1✔
2221

2222
function hcat(V::Vector{T}...) where T
62✔
2223
    height = length(V[1])
570✔
2224
    for j = 2:length(V)
570✔
2225
        if length(V[j]) != height
636✔
2226
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2227
        end
2228
    end
733✔
2229
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
569✔
2230
end
2231
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2232

2233
function vcat(arrays::Vector{T}...) where T
30,879✔
2234
    n = 0
3,218✔
2235
    for a in arrays
30,879✔
2236
        n += length(a)
2,062,193✔
2237
    end
2,093,067✔
2238
    arr = Vector{T}(undef, n)
61,738✔
2239
    nd = 1
3,218✔
2240
    for a in arrays
30,879✔
2241
        na = length(a)
2,062,193✔
2242
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,062,193✔
2243
        unsafe_copyto!(arr, nd, a, 1, na)
4,121,418✔
2244
        nd += na
2,062,193✔
2245
    end
2,093,067✔
2246
    return arr
30,879✔
2247
end
2248
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
35✔
2249

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

2252
## find ##
2253

2254
"""
2255
    findnext(A, i)
2256

2257
Find the next index after or including `i` of a `true` element of `A`,
2258
or `nothing` if not found.
2259

2260
Indices are of the same type as those returned by [`keys(A)`](@ref)
2261
and [`pairs(A)`](@ref).
2262

2263
# Examples
2264
```jldoctest
2265
julia> A = [false, false, true, false]
2266
4-element Vector{Bool}:
2267
 0
2268
 0
2269
 1
2270
 0
2271

2272
julia> findnext(A, 1)
2273
3
2274

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

2277
julia> A = [false false; true false]
2278
2×2 Matrix{Bool}:
2279
 0  0
2280
 1  0
2281

2282
julia> findnext(A, CartesianIndex(1, 1))
2283
CartesianIndex(2, 1)
2284
```
2285
"""
2286
findnext(A, start) = findnext(identity, A, start)
43,492✔
2287

2288
"""
2289
    findfirst(A)
2290

2291
Return the index or key of the first `true` value in `A`.
2292
Return `nothing` if no such value is found.
2293
To search for other kinds of values, pass a predicate as the first argument.
2294

2295
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2296
and [`pairs(A)`](@ref).
2297

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

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

2309
julia> findfirst(A)
2310
3
2311

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

2314
julia> A = [false false; true false]
2315
2×2 Matrix{Bool}:
2316
 0  0
2317
 1  0
2318

2319
julia> findfirst(A)
2320
CartesianIndex(2, 1)
2321
```
2322
"""
2323
findfirst(A) = findfirst(identity, A)
2✔
2324

2325
# Needed for bootstrap, and allows defining only an optimized findnext method
2326
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
12,104✔
2327

2328
"""
2329
    findnext(predicate::Function, A, i)
2330

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

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

2339
# Examples
2340
```jldoctest
2341
julia> A = [1, 4, 2, 2];
2342

2343
julia> findnext(isodd, A, 1)
2344
1
2345

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

2348
julia> A = [1 4; 2 2];
2349

2350
julia> findnext(isodd, A, CartesianIndex(1, 1))
2351
CartesianIndex(1, 1)
2352

2353
julia> findnext(isspace, "a b c", 3)
2354
4
2355
```
2356
"""
2357
function findnext(testf::Function, A, start)
19,531✔
2358
    i = oftype(first(keys(A)), start)
45,189✔
2359
    l = last(keys(A))
85,646,347✔
2360
    i > l && return nothing
85,646,347✔
2361
    while true
176,513,581✔
2362
        testf(A[i]) && return i
176,533,822✔
2363
        i == l && break
168,926,614✔
2364
        # nextind(A, l) can throw/overflow
2365
        i = nextind(A, i)
164,054,938✔
2366
    end
164,054,919✔
2367
    return nothing
4,871,671✔
2368
end
2369

2370
"""
2371
    findfirst(predicate::Function, A)
2372

2373
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2374
Return `nothing` if there is no such element.
2375

2376
Indices or keys 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
4-element Vector{Int64}:
2383
 1
2384
 4
2385
 2
2386
 2
2387

2388
julia> findfirst(iseven, A)
2389
2
2390

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

2393
julia> findfirst(isequal(4), A)
2394
2
2395

2396
julia> A = [1 4; 2 2]
2397
2×2 Matrix{Int64}:
2398
 1  4
2399
 2  2
2400

2401
julia> findfirst(iseven, A)
2402
CartesianIndex(2, 1)
2403
```
2404
"""
2405
function findfirst(testf::Function, A)
15✔
2406
    for (i, a) in pairs(A)
22✔
2407
        testf(a) && return i
14✔
2408
    end
11✔
2409
    return nothing
8✔
2410
end
2411

2412
# Needed for bootstrap, and allows defining only an optimized findnext method
2413
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
262,969,450✔
2414
    findnext(testf, A, first(keys(A)))
2415

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

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

2422
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2423
    isempty(r) && return nothing
6✔
2424
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2425
    d = convert(S, p.x - first(r))::S
3✔
2426
    iszero(d % step(r)) || return nothing
3✔
2427
    return d ÷ step(r) + 1
3✔
2428
end
2429

2430
"""
2431
    findprev(A, i)
2432

2433
Find the previous index before or including `i` of a `true` element of `A`,
2434
or `nothing` if not found.
2435

2436
Indices are of the same type as those returned by [`keys(A)`](@ref)
2437
and [`pairs(A)`](@ref).
2438

2439
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2440

2441
# Examples
2442
```jldoctest
2443
julia> A = [false, false, true, true]
2444
4-element Vector{Bool}:
2445
 0
2446
 0
2447
 1
2448
 1
2449

2450
julia> findprev(A, 3)
2451
3
2452

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

2455
julia> A = [false false; true true]
2456
2×2 Matrix{Bool}:
2457
 0  0
2458
 1  1
2459

2460
julia> findprev(A, CartesianIndex(2, 1))
2461
CartesianIndex(2, 1)
2462
```
2463
"""
2464
findprev(A, start) = findprev(identity, A, start)
8,326✔
2465

2466
"""
2467
    findlast(A)
2468

2469
Return the index or key of the last `true` value in `A`.
2470
Return `nothing` if there is no `true` value in `A`.
2471

2472
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2473
and [`pairs(A)`](@ref).
2474

2475
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2476

2477
# Examples
2478
```jldoctest
2479
julia> A = [true, false, true, false]
2480
4-element Vector{Bool}:
2481
 1
2482
 0
2483
 1
2484
 0
2485

2486
julia> findlast(A)
2487
3
2488

2489
julia> A = falses(2,2);
2490

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

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

2498
julia> findlast(A)
2499
CartesianIndex(2, 1)
2500
```
2501
"""
2502
findlast(A) = findlast(identity, A)
23✔
2503

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

2507
"""
2508
    findprev(predicate::Function, A, i)
2509

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

2515
Indices are of the same type as those returned by [`keys(A)`](@ref)
2516
and [`pairs(A)`](@ref).
2517

2518
# Examples
2519
```jldoctest
2520
julia> A = [4, 6, 1, 2]
2521
4-element Vector{Int64}:
2522
 4
2523
 6
2524
 1
2525
 2
2526

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

2529
julia> findprev(isodd, A, 3)
2530
3
2531

2532
julia> A = [4 6; 1 2]
2533
2×2 Matrix{Int64}:
2534
 4  6
2535
 1  2
2536

2537
julia> findprev(isodd, A, CartesianIndex(1, 2))
2538
CartesianIndex(2, 1)
2539

2540
julia> findprev(isspace, "a b c", 3)
2541
2
2542
```
2543
"""
2544
function findprev(testf::Function, A, start)
273✔
2545
    f = first(keys(A))
36,851✔
2546
    i = oftype(f, start)
36,862✔
2547
    i < f && return nothing
40,914✔
2548
    while true
308,225✔
2549
        testf(A[i]) && return i
308,420✔
2550
        i == f && break
269,761✔
2551
        # prevind(A, f) can throw/underflow
2552
        i = prevind(A, i)
267,366✔
2553
    end
267,338✔
2554
    return nothing
2,392✔
2555
end
2556

2557
"""
2558
    findlast(predicate::Function, A)
2559

2560
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2561
Return `nothing` if there is no such element.
2562

2563
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2564
and [`pairs(A)`](@ref).
2565

2566
# Examples
2567
```jldoctest
2568
julia> A = [1, 2, 3, 4]
2569
4-element Vector{Int64}:
2570
 1
2571
 2
2572
 3
2573
 4
2574

2575
julia> findlast(isodd, A)
2576
3
2577

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

2580
julia> A = [1 2; 3 4]
2581
2×2 Matrix{Int64}:
2582
 1  2
2583
 3  4
2584

2585
julia> findlast(isodd, A)
2586
CartesianIndex(2, 1)
2587
```
2588
"""
2589
function findlast(testf::Function, A)
3✔
2590
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2591
        testf(a) && return i
6✔
2592
    end
6✔
2593
    return nothing
2✔
2594
end
2595

2596
# Needed for bootstrap, and allows defining only an optimized findprev method
2597
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
14,176✔
2598
    findprev(testf, A, last(keys(A)))
2599

2600
"""
2601
    findall(f::Function, A)
2602

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

2606
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2607
and [`pairs(A)`](@ref).
2608

2609
# Examples
2610
```jldoctest
2611
julia> x = [1, 3, 4]
2612
3-element Vector{Int64}:
2613
 1
2614
 3
2615
 4
2616

2617
julia> findall(isodd, x)
2618
2-element Vector{Int64}:
2619
 1
2620
 2
2621

2622
julia> A = [1 2 0; 3 4 0]
2623
2×3 Matrix{Int64}:
2624
 1  2  0
2625
 3  4  0
2626
julia> findall(isodd, A)
2627
2-element Vector{CartesianIndex{2}}:
2628
 CartesianIndex(1, 1)
2629
 CartesianIndex(2, 1)
2630

2631
julia> findall(!iszero, A)
2632
4-element Vector{CartesianIndex{2}}:
2633
 CartesianIndex(1, 1)
2634
 CartesianIndex(2, 1)
2635
 CartesianIndex(1, 2)
2636
 CartesianIndex(2, 2)
2637

2638
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2639
Dict{Symbol, Int64} with 3 entries:
2640
  :A => 10
2641
  :B => -1
2642
  :C => 0
2643

2644
julia> findall(≥(0), d)
2645
2-element Vector{Symbol}:
2646
 :A
2647
 :C
2648

2649
```
2650
"""
2651
function findall(testf::Function, A)
26✔
2652
    gen = (first(p) for p in pairs(A) if testf(last(p)))
59✔
2653
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
59✔
2654
end
2655

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

2660
"""
2661
    findall(A)
2662

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

2667
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2668
and [`pairs(A)`](@ref).
2669

2670
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2671

2672
# Examples
2673
```jldoctest
2674
julia> A = [true, false, false, true]
2675
4-element Vector{Bool}:
2676
 1
2677
 0
2678
 0
2679
 1
2680

2681
julia> findall(A)
2682
2-element Vector{Int64}:
2683
 1
2684
 4
2685

2686
julia> A = [true false; false true]
2687
2×2 Matrix{Bool}:
2688
 1  0
2689
 0  1
2690

2691
julia> findall(A)
2692
2-element Vector{CartesianIndex{2}}:
2693
 CartesianIndex(1, 1)
2694
 CartesianIndex(2, 2)
2695

2696
julia> findall(falses(3))
2697
Int64[]
2698
```
2699
"""
2700
function findall(A)
4✔
2701
    collect(first(p) for p in pairs(A) if last(p))
4✔
2702
end
2703

2704
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2705
function findall(A::AbstractArray{Bool})
823✔
2706
    n = count(A)
3,722✔
2707
    I = Vector{eltype(keys(A))}(undef, n)
7,062✔
2708
    cnt = 1
3,717✔
2709
    for (i,a) in pairs(A)
7,426✔
2710
        if a
212,268✔
2711
            I[cnt] = i
128,972✔
2712
            cnt += 1
128,972✔
2713
        end
2714
    end
420,824✔
2715
    I
3,717✔
2716
end
2717

2718
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2719
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2720
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2721

2722
# similar to Matlab's ismember
2723
"""
2724
    indexin(a, b)
2725

2726
Return an array containing the first index in `b` for
2727
each value in `a` that is a member of `b`. The output
2728
array contains `nothing` wherever `a` is not a member of `b`.
2729

2730
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2731

2732
# Examples
2733
```jldoctest
2734
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2735

2736
julia> b = ['a', 'b', 'c'];
2737

2738
julia> indexin(a, b)
2739
6-element Vector{Union{Nothing, Int64}}:
2740
 1
2741
 2
2742
 3
2743
 2
2744
  nothing
2745
 1
2746

2747
julia> indexin(b, a)
2748
3-element Vector{Union{Nothing, Int64}}:
2749
 1
2750
 2
2751
 3
2752
```
2753
"""
2754
function indexin(a, b::AbstractArray)
7✔
2755
    inds = keys(b)
7✔
2756
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2757
    for (val, ind) in zip(b, inds)
14✔
2758
        get!(bdict, val, ind)
30✔
2759
    end
53✔
2760
    return Union{eltype(inds), Nothing}[
7✔
2761
        get(bdict, i, nothing) for i in a
2762
    ]
2763
end
2764

2765
function _findin(a::Union{AbstractArray, Tuple}, b)
375✔
2766
    ind  = Vector{eltype(keys(a))}()
561✔
2767
    bset = Set(b)
377✔
2768
    @inbounds for (i,ai) in pairs(a)
606✔
2769
        ai in bset && push!(ind, i)
90,559✔
2770
    end
180,565✔
2771
    ind
375✔
2772
end
2773

2774
# If two collections are already sorted, _findin can be computed with
2775
# a single traversal of the two collections. This is much faster than
2776
# using a hash table (although it has the same complexity).
2777
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
3✔
2778
    viter, witer = keys(v), eachindex(w)
9✔
2779
    out  = eltype(viter)[]
9✔
2780
    vy, wy = iterate(viter), iterate(witer)
11✔
2781
    if vy === nothing || wy === nothing
17✔
2782
        return out
2✔
2783
    end
2784
    viteri, i = vy
7✔
2785
    witerj, j = wy
7✔
2786
    @inbounds begin
7✔
2787
        vi, wj = v[viteri], w[witerj]
7✔
2788
        while true
54✔
2789
            if isless(vi, wj)
56✔
2790
                vy = iterate(viter, i)
25✔
2791
                if vy === nothing
14✔
2792
                    break
2✔
2793
                end
2794
                viteri, i = vy
12✔
2795
                vi        = v[viteri]
12✔
2796
            elseif isless(wj, vi)
40✔
2797
                wy = iterate(witer, j)
44✔
2798
                if wy === nothing
24✔
2799
                    break
4✔
2800
                end
2801
                witerj, j = wy
20✔
2802
                wj        = w[witerj]
20✔
2803
            else
2804
                push!(out, viteri)
16✔
2805
                vy = iterate(viter, i)
25✔
2806
                if vy === nothing
16✔
2807
                    break
1✔
2808
                end
2809
                # We only increment the v iterator because v can have
2810
                # repeated matches to a single value in w
2811
                viteri, i = vy
15✔
2812
                vi        = v[viteri]
15✔
2813
            end
2814
        end
47✔
2815
    end
2816
    return out
7✔
2817
end
2818

2819
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2820
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2821
        return _sortedfindin(x, pred.x)
9✔
2822
    else
2823
        return _findin(x, pred.x)
6✔
2824
    end
2825
end
2826
# issorted fails for some element types so the method above has to be restricted
2827
# to element with isless/< defined.
2828
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
373✔
2829
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2830

2831
# Copying subregions
2832
function indcopy(sz::Dims, I::Vector)
1✔
2833
    n = length(I)
1✔
2834
    s = sz[n]
1✔
2835
    for i = n+1:length(sz)
2✔
2836
        s *= sz[i]
×
2837
    end
×
2838
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2839
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2840
    dst, src
1✔
2841
end
2842

2843
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2844
    n = length(I)
1✔
2845
    s = sz[n]
1✔
2846
    for i = n+1:length(sz)
1✔
2847
        s *= sz[i]
×
2848
    end
×
2849
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2850
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2851
    dst, src
1✔
2852
end
2853

2854
## Filter ##
2855

2856
"""
2857
    filter(f, a)
2858

2859
Return a copy of collection `a`, removing elements for which `f` is `false`.
2860
The function `f` is passed one argument.
2861

2862
!!! compat "Julia 1.4"
2863
    Support for `a` as a tuple requires at least Julia 1.4.
2864

2865
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2866

2867
# Examples
2868
```jldoctest
2869
julia> a = 1:10
2870
1:10
2871

2872
julia> filter(isodd, a)
2873
5-element Vector{Int64}:
2874
 1
2875
 3
2876
 5
2877
 7
2878
 9
2879
```
2880
"""
2881
function filter(f, a::Array{T, N}) where {T, N}
26,978✔
2882
    j = 1
15,180✔
2883
    b = Vector{T}(undef, length(a))
53,800✔
2884
    for ai in a
26,978✔
2885
        @inbounds b[j] = ai
3,302,442✔
2886
        j = ifelse(f(ai)::Bool, j+1, j)
3,303,597✔
2887
    end
3,302,442✔
2888
    resize!(b, j-1)
26,978✔
2889
    sizehint!(b, length(b))
26,978✔
2890
    b
15,180✔
2891
end
2892

2893
function filter(f, a::AbstractArray)
455✔
2894
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
455✔
2895

2896
    j = 1
455✔
2897
    idxs = Vector{Int}(undef, length(a))
748✔
2898
    for idx in eachindex(a)
458✔
2899
        @inbounds idxs[j] = idx
103,477✔
2900
        ai = @inbounds a[idx]
103,477✔
2901
        j = ifelse(f(ai)::Bool, j+1, j)
105,010✔
2902
    end
206,660✔
2903
    resize!(idxs, j-1)
454✔
2904
    res = a[idxs]
454✔
2905
    empty!(idxs)
4,152✔
2906
    sizehint!(idxs, 0)
454✔
2907
    return res
454✔
2908
end
2909

2910
"""
2911
    filter!(f, a)
2912

2913
Update collection `a`, removing elements for which `f` is `false`.
2914
The function `f` is passed one argument.
2915

2916
# Examples
2917
```jldoctest
2918
julia> filter!(isodd, Vector(1:10))
2919
5-element Vector{Int64}:
2920
 1
2921
 3
2922
 5
2923
 7
2924
 9
2925
```
2926
"""
2927
function filter!(f, a::AbstractVector)
1,071,496✔
2928
    j = firstindex(a)
1,117✔
2929
    for ai in a
113,625,125✔
2930
        @inbounds a[j] = ai
132,601,410✔
2931
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
132,632,295✔
2932
    end
132,601,419✔
2933
    j > lastindex(a) && return a
113,625,124✔
2934
    if a isa Vector
384✔
2935
        resize!(a, j-1)
86,481✔
2936
        sizehint!(a, j-1)
86,481✔
2937
    else
2938
        deleteat!(a, j:lastindex(a))
1✔
2939
    end
2940
    return a
86,482✔
2941
end
2942

2943
"""
2944
    filter(f)
2945

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

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

2952
# Examples
2953
```jldoctest
2954
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2955
(1, 2, 4, 6)
2956

2957
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2958
3-element Vector{Vector{Int64}}:
2959
 [2]
2960
 [2, 4]
2961
 [4]
2962
```
2963
!!! compat "Julia 1.9"
2964
    This method requires at least Julia 1.9.
2965
"""
2966
function filter(f)
1✔
2967
    Fix1(filter, f)
1✔
2968
end
2969

2970
"""
2971
    keepat!(a::Vector, inds)
2972
    keepat!(a::BitVector, inds)
2973

2974
Remove the items at all the indices which are not given by `inds`,
2975
and return the modified `a`.
2976
Items which are kept are shifted to fill the resulting gaps.
2977

2978
$(_DOCS_ALIASING_WARNING)
2979

2980
`inds` must be an iterator of sorted and unique integer indices.
2981
See also [`deleteat!`](@ref).
2982

2983
!!! compat "Julia 1.7"
2984
    This function is available as of Julia 1.7.
2985

2986
# Examples
2987
```jldoctest
2988
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
2989
3-element Vector{Int64}:
2990
 6
2991
 4
2992
 2
2993
```
2994
"""
2995
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
2996

2997
"""
2998
    keepat!(a::Vector, m::AbstractVector{Bool})
2999
    keepat!(a::BitVector, m::AbstractVector{Bool})
3000

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

3005
# Examples
3006
```jldoctest
3007
julia> a = [:a, :b, :c];
3008

3009
julia> keepat!(a, [true, false, true])
3010
2-element Vector{Symbol}:
3011
 :a
3012
 :c
3013

3014
julia> a
3015
2-element Vector{Symbol}:
3016
 :a
3017
 :c
3018
```
3019
"""
3020
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
3021

3022
# set-like operators for vectors
3023
# These are moderately efficient, preserve order, and remove dupes.
3024

3025
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
325,109✔
3026
    # P, U force specialization
3027
    if pred(x, state)
638,839✔
3028
        update!(state, x)
18,664✔
3029
        true
3030
    else
3031
        false
3032
    end
3033
end
3034

3035
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
289✔
3036
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
3,785✔
3037

3038
function _grow!(pred!, v::AbstractVector, itrs)
109✔
3039
    filter!(pred!, v) # uniquify v
316✔
3040
    for itr in itrs
316✔
3041
        mapfilter(pred!, push!, itr, v)
619✔
3042
    end
915✔
3043
    return v
316✔
3044
end
3045

3046
union!(v::AbstractVector{T}, itrs...) where {T} =
302✔
3047
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3048

3049
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
3050
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3051

3052
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
2✔
3053
    seen = Set{eltype(v)}()
6✔
3054
    filter!(_grow_filter!(seen), v)
6✔
3055
    shrinker!(seen, itrs...)
6✔
3056
    filter!(in(seen), v)
6✔
3057
end
3058

3059
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
3060
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
3061

3062
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
3,753✔
3063

3064
function _shrink(shrinker!::F, itr, itrs) where F
3,655✔
3065
    T = promote_eltype(itr, itrs...)
3,557✔
3066
    keep = shrinker!(Set{T}(itr), itrs...)
4,715✔
3067
    vectorfilter(T, _shrink_filter!(keep), itr)
3,694✔
3068
end
3069

3070
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
511✔
3071
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
3,185✔
3072

3073
function intersect(v::AbstractVector, r::AbstractRange)
7✔
3074
    T = promote_eltype(v, r)
11✔
3075
    common = Iterators.filter(in(r), v)
59✔
3076
    seen = Set{T}(common)
59✔
3077
    return vectorfilter(T, _shrink_filter!(seen), common)
59✔
3078
end
3079
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
3080

3081
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3082
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
3,852✔
3083
    if i isa Bool # Not via dispatch to avoid ambiguities
31,317,398✔
3084
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3085
    else
3086
        _getindex(v, i)
520,768,126✔
3087
    end
3088
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