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

JuliaLang / julia / #37767

02 May 2024 04:02AM UTC coverage: 85.708% (-1.7%) from 87.428%
#37767

push

local

web-flow
Pass CodeGenOpt::Less to LLVM at O1 (rather than CodeGenOpt::None). (#37893)

For context, please see
https://github.com/JuliaLang/julia/pull/35086#issuecomment-700944522.
Regarding alignment with clang, please see
https://reviews.llvm.org/D28409
(/https://github.com/JuliaLang/julia/pull/35086#issuecomment-598282810).

```
Prior to Julia 1.5, Julia passed CodeGenOpt::Aggressive to LLVM at -O1.
As of Julia 1.5, Julia passes CodeGenOpt::None to LLVM at -O1.

This reduction in optimization effort at -O1 improved compilation latency,
but induced appreciable runtime regressions.

This commit makes Julia pass CodeGenOpt::Less to LLVM at -O1,
mitigating the runtime regressions caused by CodeGenOpt::None,
while retaining most of CodeGenOpt::None's latency improvements.

This commit also aligns Julia's CodeGenOpt selection at -O1
with that of clang.
```

Best! :)

74571 of 87006 relevant lines covered (85.71%)

14871255.36 hits per line

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

93.54
/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,517✔
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}()
28,640,853✔
159
function vect(X::T...) where T
48,271✔
160
    @_terminates_locally_meta
96,580✔
161
    vec = Vector{T}(undef, length(X))
1,428,250✔
162
    @_safeindex for i = 1:length(X)
221,768✔
163
        vec[i] = X[i]
4,528,485✔
164
    end
6,471,307✔
165
    return vec
176,875✔
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,766✔
184
    T = promote_typeof(X...)
56,568✔
185
    return T[X...]
56,748✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
10,555✔
190
    d < 1 && error("arraysize: dimension out of range")
61,358,432✔
191
    sz = getfield(a, :size)
61,475,771✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
85,606,856✔
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))
6,214✔
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)
43,720✔
215

216
function _unsetindex!(A::Array, i::Int)
217
    @inline
10,982,085✔
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
×
224
    @boundscheck checkbounds(A, i...)
×
225
    @inbounds _unsetindex!(A, _to_linear_index(A, i...))
×
226
    return A
×
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)
243,767✔
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,788,594✔
241

242
function isassigned(a::Array, i::Int...)
110,330✔
243
    @inline
1,655,656✔
244
    @_noub_if_noinbounds_meta
1,655,656✔
245
    @boundscheck checkbounds(Bool, a, i...) || return false
1,655,668✔
246
    ii = _sub2ind(size(a), i...)
1,655,648✔
247
    return @inbounds isassigned(memoryref(a.ref, ii, false))
1,655,648✔
248
end
249

250
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
165✔
251
    @inline
27,651,809✔
252
    @_noub_if_noinbounds_meta
27,651,809✔
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))
25,470,912✔
274
    return dest
24,857,735✔
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
11,384,895✔
289
    unsafe_copyto!(GenericMemoryRef(dest.ref, doffs), GenericMemoryRef(src.ref, soffs), n)
14,305,326✔
290
    return dest
7,152,666✔
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,000✔
300
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
17✔
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)
208,246,497✔
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
129,854,599✔
308
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
99,212,901✔
309
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
99,212,920✔
310
    @boundscheck checkbounds(src, soffs:soffs+n-1)
99,212,881✔
311
    @inbounds let dest = GenericMemoryRef(dest isa Array ? getfield(dest, :ref) : dest, doffs)
99,212,875✔
312
                  src = GenericMemoryRef(src isa Array ? getfield(src, :ref) : src, soffs)
99,212,886✔
313
        unsafe_copyto!(dest, src, n)
198,425,719✔
314
    end
315
    return dest
99,212,634✔
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,883✔
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))
33,502,627✔
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
258,646✔
333
    for i in eachindex(dest)
773,316,269✔
334
        @inbounds dest[i] = xT
2,147,483,647✔
335
    end
2,147,483,647✔
336
    return dest
773,316,269✔
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,292✔
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
284,364✔
354
    ref = a.ref
156,301,019✔
355
    newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a))
156,301,021✔
356
    return $(Expr(:new, :(typeof(a)), :(Core.memoryref(newmem)), :(a.size)))
156,300,904✔
357
end
358

359
## Constructors ##
360

361
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
233,816✔
362
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
7,725✔
363
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
15,013✔
364
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
26,218✔
365
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
3,631,959✔
366
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
75,149,455✔
367
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
499✔
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,932✔
392
    @inline
153,121✔
393
    @_effect_free_terminates_locally_meta
153,121✔
394
    a = Vector{T}(undef, length(vals))
820,081,114✔
395
    if vals isa NTuple
153,153✔
396
        @_safeindex for i in 1:length(vals)
96,962✔
397
            a[i] = vals[i]
57,418,661✔
398
        end
240,156✔
399
    else
400
        # use afoldl to avoid type instability inside loop
401
        afoldl(1, vals...) do i, v
59,425✔
402
            @inbounds a[i] = v
125,225✔
403
            return i + 1
125,211✔
404
        end
405
    end
406
    return a
156,395✔
407
end
408

409
function getindex(::Type{Any}, @nospecialize vals...)
27,360,766✔
410
    @_effect_free_terminates_locally_meta
660✔
411
    a = Vector{Any}(undef, length(vals))
91,770,671✔
412
    @_safeindex for i = 1:length(vals)
34,512,394✔
413
        a[i] = vals[i]
127,094,126✔
414
    end
138,623,150✔
415
    return a
27,524,813✔
416
end
417
getindex(::Type{Any}) = Vector{Any}()
37,031,986✔
418

419
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
5✔
420
    ref = a.ref
11,238,413✔
421
    t = @_gc_preserve_begin ref
11,238,413✔
422
    p = unsafe_convert(Ptr{Cvoid}, ref)
11,238,413✔
423
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
11,238,416✔
424
    @_gc_preserve_end t
11,238,410✔
425
    return a
11,238,410✔
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)
131✔
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,074✔
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,180✔
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,160✔
584
            a = Array{T,N}(undef, dims)
159,369,795✔
585
            fill!(a, $felt(T))
2,147,483,647✔
586
            return a
110,425,294✔
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
## Conversions ##
602

603
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
291,482✔
604

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

607
## Constructors ##
608

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

615
## copying iterators to containers
616

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

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

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

634
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
39,567✔
635
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
636
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
22,630,946✔
637
    a = Vector{T}()
22,630,955✔
638
    for x in itr
38,913,174✔
639
        push!(a, x)
109,304,288✔
640
    end
202,326,356✔
641
    return a
22,630,955✔
642
end
643

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

647
_similar_shape(itr, ::SizeUnknown) = nothing
×
648
_similar_shape(itr, ::HasLength) = length(itr)::Integer
45,380,285✔
649
_similar_shape(itr, ::HasShape) = axes(itr)
551,186,741✔
650

651
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,212,714✔
652
    similar(c, T, 0)
653
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
12,359,718✔
654
    similar(c, T, len)
655
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
294,166✔
656
    similar(c, T, axs)
657

658
# make a collection appropriate for collecting `itr::Generator`
659
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
141✔
660
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
55,121,844✔
661
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
965,700,140✔
662

663
# used by syntax lowering for simple typed comprehensions
664
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
1,019,166,786✔
665

666

667
"""
668
    collect(collection)
669

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

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

679
# Examples
680

681
Collect items from a `UnitRange{Int64}` collection:
682

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

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

693
```jldoctest
694
julia> collect(x^2 for x in 1:3)
695
3-element Vector{Int64}:
696
 1
697
 4
698
 9
699
```
700
"""
701
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
13,788,375✔
702

703
collect(A::AbstractArray) = _collect_indices(axes(A), A)
132,244✔
704

705
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
189,014✔
706

707
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
12,346,765✔
708
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
709

710
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,212,500✔
711
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,212,554✔
712
    for x in itr
2,423,112✔
713
        push!(a,x)
9,950,837✔
714
    end
17,046,300✔
715
    return a
1,212,553✔
716
end
717

718
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
3✔
719
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
134,488✔
720
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
721
function _collect_indices(indsA, A)
1✔
722
    B = Array{eltype(A)}(undef, length.(indsA))
41✔
723
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
23✔
724
end
725

726
# NOTE: this function is not meant to be called, only inferred, for the
727
# purpose of bounding the types of values generated by an iterator.
728
function _iterator_upper_bound(itr)
×
729
    x = iterate(itr)
×
730
    while x !== nothing
×
731
        val = getfield(x, 1)
×
732
        if inferencebarrier(nothing)
×
733
            return val
×
734
        end
735
        x = iterate(itr, getfield(x, 2))
×
736
    end
×
737
    throw(nothing)
×
738
end
739

740
# define this as a macro so that the call to Core.Compiler
741
# gets inlined into the caller before recursion detection
742
# gets a chance to see it, so that recursive calls to the caller
743
# don't trigger the inference limiter
744
if isdefined(Core, :Compiler)
745
    macro default_eltype(itr)
746
        I = esc(itr)
747
        return quote
748
            if $I isa Generator && ($I).f isa Type
525,351✔
749
                T = ($I).f
12,745✔
750
            else
751
                T = Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)})
512,606✔
752
            end
753
            promote_typejoin_union(T)
525,456✔
754
        end
755
    end
756
else
757
    macro default_eltype(itr)
758
        I = esc(itr)
759
        return quote
760
            if $I isa Generator && ($I).f isa Type
761
                promote_typejoin_union($I.f)
762
            else
763
                Any
764
            end
765
        end
766
    end
767
end
768

769
function collect(itr::Generator)
907,339✔
770
    isz = IteratorSize(itr.iter)
388,910✔
771
    et = @default_eltype(itr)
772
    if isa(isz, SizeUnknown)
388,910✔
773
        return grow_to!(Vector{et}(), itr)
94,674✔
774
    else
775
        shp = _similar_shape(itr, isz)
823,556✔
776
        y = iterate(itr)
1,628,587✔
777
        if y === nothing
822,930✔
778
            return _array_for(et, isz, shp)
7,086✔
779
        end
780
        v1, st = y
387,496✔
781
        dest = _array_for(typeof(v1), isz, shp)
1,620,173✔
782
        # The typeassert gives inference a helping hand on the element type and dimensionality
783
        # (work-around for #28382)
784
        et′ = et <: Type ? Type : et
387,496✔
785
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
387,646✔
786
        collect_to_with_first!(dest, v1, itr, st)::RT
10,805,894✔
787
    end
788
end
789

790
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
84✔
791
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
792

793
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
189,030✔
794
    et = @default_eltype(itr)
122,204✔
795
    shp = _similar_shape(itr, isz)
189,037✔
796
    y = iterate(itr)
375,996✔
797
    if y === nothing
189,035✔
798
        return _similar_for(c, et, itr, isz, shp)
2,051✔
799
    end
800
    v1, st = y
121,119✔
801
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
290,491✔
802
    # The typeassert gives inference a helping hand on the element type and dimensionality
803
    # (work-around for #28382)
804
    et′ = et <: Type ? Type : et
121,097✔
805
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
121,110✔
806
    collect_to_with_first!(dest, v1, itr, st)::RT
186,984✔
807
end
808

809
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
86,088✔
810
    i1 = first(LinearIndices(dest))
508,593✔
811
    dest[i1] = v1
1,002,874✔
812
    return collect_to!(dest, itr, i1+1, st)
12,086,415✔
813
end
814

815
function collect_to_with_first!(dest, v1, itr, st)
×
816
    push!(dest, v1)
×
817
    return grow_to!(dest, itr, st)
×
818
end
819

820
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
227✔
821
    @inline
357✔
822
    new = similar(dest, promote_typejoin(T, typeof(el)))
802✔
823
    f = first(LinearIndices(dest))
357✔
824
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
799✔
825
    @inbounds new[i] = el
402✔
826
    return new
402✔
827
end
828

829
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
127,461✔
830
    # collect to dest array, checking the type of each result. if a result does not
831
    # match, widen the result type and re-dispatch.
832
    i = offs
508,950✔
833
    while true
91,497,260✔
834
        y = iterate(itr, st)
181,991,615✔
835
        y === nothing && break
91,497,250✔
836
        el, st = y
88,734,441✔
837
        if el isa T
88,742,073✔
838
            @inbounds dest[i] = el
90,493,984✔
839
            i += 1
90,493,984✔
840
        else
841
            new = setindex_widen_up_to(dest, el, i)
402✔
842
            return collect_to!(new, itr, i+1, st)
402✔
843
        end
844
    end
90,493,984✔
845
    return dest
1,002,864✔
846
end
847

848
function grow_to!(dest, itr)
1,187✔
849
    y = iterate(itr)
1,680✔
850
    y === nothing && return dest
1,355✔
851
    dest2 = empty(dest, typeof(y[1]))
434✔
852
    push!(dest2, y[1])
506✔
853
    grow_to!(dest2, itr, y[2])
413✔
854
end
855

856
function push_widen(dest, el)
7✔
857
    @inline
10✔
858
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
11✔
859
    if new isa AbstractSet
10✔
860
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
861
        union!(new, dest)
1✔
862
    else
863
        append!(new, dest)
18✔
864
    end
865
    push!(new, el)
10✔
866
    return new
10✔
867
end
868

869
function grow_to!(dest, itr, st)
409✔
870
    T = eltype(dest)
227✔
871
    y = iterate(itr, st)
675✔
872
    while y !== nothing
4,841✔
873
        el, st = y
3,080✔
874
        if el isa T
2,740✔
875
            push!(dest, el)
4,422✔
876
        else
877
            new = push_widen(dest, el)
13✔
878
            return grow_to!(new, itr, st)
10✔
879
        end
880
        y = iterate(itr, st)
6,590✔
881
    end
4,419✔
882
    return dest
412✔
883
end
884

885
## Iteration ##
886

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

889
## Indexing: getindex ##
890

891
"""
892
    getindex(collection, key...)
893

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

897
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
898

899
# Examples
900
```jldoctest
901
julia> A = Dict("a" => 1, "b" => 2)
902
Dict{String, Int64} with 2 entries:
903
  "b" => 2
904
  "a" => 1
905

906
julia> getindex(A, "a")
907
1
908
```
909
"""
910
function getindex end
911

912
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
119,802✔
913
    @inline
192,911,728✔
914
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
204,596,385✔
915
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
204,596,753✔
916
end
917

918
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
919
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
7,426✔
920
    @inline
870,621✔
921
    @boundscheck checkbounds(A, I)
49,363,358✔
922
    lI = length(I)
49,363,367✔
923
    X = similar(A, axes(I))
74,140,936✔
924
    if lI > 0
49,363,356✔
925
        copyto!(X, firstindex(X), A, first(I), lI)
49,555,148✔
926
    end
927
    return X
49,363,356✔
928
end
929

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

933
function getindex(A::Array, c::Colon)
6✔
934
    lI = length(A)
1,810,843✔
935
    X = similar(A, lI)
3,621,684✔
936
    if lI > 0
1,810,843✔
937
        unsafe_copyto!(X, 1, A, 1, lI)
3,621,682✔
938
    end
939
    return X
1,810,843✔
940
end
941

942
# This is redundant with the abstract fallbacks, but needed for bootstrap
943
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
137✔
944
    return S[ A[i] for i in I ]
13,035,613✔
945
end
946

947
## Indexing: setindex! ##
948

949
"""
950
    setindex!(collection, value, key...)
951

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

955
# Examples
956
```jldoctest
957
julia> a = Dict("a"=>1)
958
Dict{String, Int64} with 1 entry:
959
  "a" => 1
960

961
julia> setindex!(a, 2, "b")
962
Dict{String, Int64} with 2 entries:
963
  "b" => 2
964
  "a" => 1
965
```
966
"""
967
function setindex! end
968

969
function setindex!(A::Array{T}, x, i::Int) where {T}
5,490,733✔
970
    @_noub_if_noinbounds_meta
708,407,024✔
971
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
2,147,483,647✔
972
    memoryrefset!(memoryref(A.ref, i, false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
2,147,483,647✔
973
    return A
2,147,483,647✔
974
end
975
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,494✔
976
    @inline
69,402,594✔
977
    @_noub_if_noinbounds_meta
69,402,594✔
978
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
72,361,723✔
979
    memoryrefset!(memoryref(A.ref, _to_linear_index(A, i1, i2, I...), false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
72,362,567✔
980
    return A
72,361,699✔
981
end
982

983
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
1,404,885✔
984
    memoryrefset!(memoryref(A.ref, i, false), x, :not_atomic, false); return A)
280,957,683✔
985
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
411,423✔
986
    memoryrefset!(memoryref(A.ref, i, false), x, :not_atomic, false); return A)
2,147,483,647✔
987
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
988
    __safe_setindex!(A, convert(T, x)::T, i))
36,123✔
989

990
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
991
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
91✔
992
    @_propagate_inbounds_meta
816,704✔
993
    @boundscheck setindex_shape_check(X, length(I))
8,112,038✔
994
    @boundscheck checkbounds(A, I)
8,112,038✔
995
    require_one_based_indexing(X)
816,704✔
996
    X′ = unalias(A, X)
816,704✔
997
    I′ = unalias(A, I)
816,704✔
998
    count = 1
816,704✔
999
    for i in I′
8,112,293✔
1000
        @inbounds A[i] = X′[count]
19,237,886✔
1001
        count += 1
19,237,880✔
1002
    end
31,596,839✔
1003
    return A
8,112,038✔
1004
end
1005

1006
# Faster contiguous setindex! with copyto!
1007
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
109✔
1008
    @inline
1,008,413✔
1009
    @boundscheck checkbounds(A, I)
1,008,648✔
1010
    lI = length(I)
1,008,648✔
1011
    @boundscheck setindex_shape_check(X, lI)
1,008,648✔
1012
    if lI > 0
1,008,648✔
1013
        unsafe_copyto!(A, first(I), X, 1, lI)
2,016,990✔
1014
    end
1015
    return A
1,008,648✔
1016
end
1017
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
40✔
1018
    @inline
71✔
1019
    lI = length(A)
71✔
1020
    @boundscheck setindex_shape_check(X, lI)
71✔
1021
    if lI > 0
71✔
1022
        unsafe_copyto!(A, 1, X, 1, lI)
142✔
1023
    end
1024
    return A
71✔
1025
end
1026

1027
# Pick new memory size for efficiently growing an array
1028
# TODO: This should know about the size of our GC pools
1029
# Specifically we are wasting ~10% of memory for small arrays
1030
# by not picking memory sizes that max out a GC pool
1031
function overallocation(maxsize)
1032
    maxsize < 8 && return 8;
1,063,283,414✔
1033
    # compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
1034
    # for small n, we grow faster than O(n)
1035
    # for large n, we grow at O(n/8)
1036
    # and as we reach O(memory) for memory>>1MB,
1037
    # this means we end by adding about 10% of memory each time
1038
    exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
76,324,569✔
1039
    maxsize += (1 << div(exp2 * 7, 8)) * 4 + div(maxsize, 8)
76,324,569✔
1040
    return maxsize
76,324,569✔
1041
end
1042

1043
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
2,090,330,966✔
1044

1045
function _growbeg!(a::Vector, delta::Integer)
38✔
1046
    @_noub_meta
18,975✔
1047
    delta = Int(delta)
18,975✔
1048
    delta == 0 && return # avoid attempting to index off the end
21,021,295✔
1049
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
21,020,723✔
1050
    ref = a.ref
60,530,348✔
1051
    mem = ref.mem
60,530,348✔
1052
    len = length(a)
60,530,348✔
1053
    offset = memoryrefoffset(ref)
60,530,348✔
1054
    newlen = len + delta
60,530,348✔
1055
    setfield!(a, :size, (newlen,))
60,530,348✔
1056
    # if offset is far enough advanced to fit data in existing memory without copying
1057
    if delta <= offset - 1
60,530,348✔
1058
        setfield!(a, :ref, @inbounds GenericMemoryRef(ref, 1 - delta))
38,806,952✔
1059
    else
1060
        @noinline (function()
43,446,844✔
1061
        memlen = length(mem)
21,723,449✔
1062
        if offset + len - 1 > memlen || offset < 1
43,446,898✔
1063
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1064
        end
1065
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1066
        # the +1 is because I didn't want to have an off by 1 error.
1067
        newmemlen = max(overallocation(memlen), len + 2 * delta + 1)
32,677,970✔
1068
        newoffset = div(newmemlen - newlen, 2) + 1
21,723,449✔
1069
        # If there is extra data after the end of the array we can use that space so long as there is enough
1070
        # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1071
        # Specifically, we want to ensure that we will only do this operation once before
1072
        # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1073
        if newoffset + newlen < memlen
21,723,449✔
1074
            newoffset = div(memlen - newlen, 2) + 1
×
1075
            newmem = mem
×
1076
        else
1077
            newmem = array_new_memory(mem, newmemlen)
21,723,449✔
1078
        end
1079
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
43,434,850✔
1080
        if ref !== a.ref
21,723,449✔
1081
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1082
        end
1083
        setfield!(a, :ref, @inbounds GenericMemoryRef(newmem, newoffset))
21,723,449✔
1084
        end)()
1085
    end
1086
    return
60,530,348✔
1087
end
1088

1089
function _growend!(a::Vector, delta::Integer)
28✔
1090
    @_noub_meta
6,992,530✔
1091
    delta = Int(delta)
7,011,460✔
1092
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,031,707,322✔
1093
    ref = a.ref
2,147,483,647✔
1094
    mem = ref.mem
2,147,483,647✔
1095
    memlen = length(mem)
2,147,483,647✔
1096
    len = length(a)
2,147,483,647✔
1097
    newlen = len + delta
2,147,483,647✔
1098
    offset = memoryrefoffset(ref)
2,147,483,647✔
1099
    setfield!(a, :size, (newlen,))
2,147,483,647✔
1100
    newmemlen = offset + newlen - 1
2,147,483,647✔
1101
    if memlen < newmemlen
2,147,483,647✔
1102
        @noinline (function()
2,044,548,187✔
1103
        if offset + len - 1 > memlen || offset < 1
2,044,545,720✔
1104
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1105
        end
1106

1107
        if offset - 1 > div(5 * newlen, 4)
1,022,272,860✔
1108
            # If the offset is far enough that we can copy without resizing
1109
            # while maintaining proportional spacing on both ends of the array
1110
            # note that this branch prevents infinite growth when doing combinations
1111
            # of push! and popfirst! (i.e. when using a Vector as a queue)
1112
            newmem = mem
21,733✔
1113
            newoffset = div(newlen, 8) + 1
21,733✔
1114
        else
1115
            # grow either by our computed overallocation factor
1116
            # or exactly the requested size, whichever is larger
1117
            # TODO we should possibly increase the offset if the current offset is nonzero.
1118
            newmemlen2 = max(overallocation(memlen), newmemlen)
1,080,230,866✔
1119
            newmem = array_new_memory(mem, newmemlen2)
2,044,483,303✔
1120
            newoffset = offset
1,022,251,127✔
1121
        end
1122
        newref = @inbounds GenericMemoryRef(newmem, newoffset)
1,022,272,860✔
1123
        unsafe_copyto!(newref, ref, len)
1,114,101,915✔
1124
        if ref !== a.ref
1,022,272,860✔
1125
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1126
        end
1127
        setfield!(a, :ref, newref)
1,022,272,860✔
1128
        end)()
1129
    end
1130
    return
2,147,483,647✔
1131
end
1132

1133
function _growat!(a::Vector, i::Integer, delta::Integer)
90,705,154✔
1134
    @_terminates_globally_noub_meta
293,959✔
1135
    delta = Int(delta)
293,959✔
1136
    i = Int(i)
293,959✔
1137
    i == 1 && return _growbeg!(a, delta)
90,705,154✔
1138
    len = length(a)
70,127,666✔
1139
    i == len + 1 && return _growend!(a, delta)
70,127,666✔
1140
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
70,065,391✔
1141
    1 < i <= len || throw(BoundsError(a, i))
70,065,393✔
1142
    ref = a.ref
70,065,389✔
1143
    mem = ref.mem
70,065,389✔
1144
    memlen = length(mem)
70,065,389✔
1145
    newlen = len + delta
70,065,389✔
1146
    offset = memoryrefoffset(ref)
70,065,389✔
1147
    setfield!(a, :size, (newlen,))
70,065,389✔
1148
    newmemlen = offset + newlen - 1
70,065,389✔
1149

1150
    # which side would we rather grow into?
1151
    prefer_start = i <= div(len, 2)
70,065,389✔
1152
    # if offset is far enough advanced to fit data in beginning of the memory
1153
    if prefer_start && delta <= offset - 1
70,065,389✔
1154
        newref = @inbounds GenericMemoryRef(mem, offset - delta)
28,391,577✔
1155
        unsafe_copyto!(newref, ref, i)
56,783,154✔
1156
        setfield!(a, :ref, newref)
28,391,577✔
1157
        for j in i:i+delta-1
28,391,577✔
1158
            @inbounds _unsetindex!(a, j)
40,054,846✔
1159
        end
40,048,021✔
1160
    elseif !prefer_start && memlen >= newmemlen
41,673,812✔
1161
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
59,304,108✔
1162
        for j in i:i+delta-1
29,652,054✔
1163
            @inbounds _unsetindex!(a, j)
41,120,903✔
1164
        end
41,111,590✔
1165
    else
1166
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1167
        # the +1 is because I didn't want to have an off by 1 error.
1168
        newmemlen = max(overallocation(memlen), len+2*delta+1)
17,602,135✔
1169
        newoffset = (newmemlen - newlen) ÷ 2 + 1
12,021,758✔
1170
        newmem = array_new_memory(mem, newmemlen)
24,043,516✔
1171
        newref = @inbounds GenericMemoryRef(newmem, newoffset)
12,021,758✔
1172
        unsafe_copyto!(newref, ref, i-1)
24,043,516✔
1173
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
24,043,516✔
1174
        setfield!(a, :ref, newref)
12,021,758✔
1175
    end
1176
end
1177

1178
# efficiently delete part of an array
1179
function _deletebeg!(a::Vector, delta::Integer)
17,409,917✔
1180
    delta = Int(delta)
1,083,445✔
1181
    len = length(a)
62,177,265✔
1182
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
62,177,265✔
1183
    for i in 1:delta
18,584,283✔
1184
        @inbounds _unsetindex!(a, i)
85,407,904✔
1185
    end
30,148,473✔
1186
    newlen = len - delta
62,177,265✔
1187
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
62,177,265✔
1188
        newref = @inbounds GenericMemoryRef(a.ref, delta + 1)
56,254,645✔
1189
        setfield!(a, :ref, newref)
56,254,645✔
1190
    end
1191
    setfield!(a, :size, (newlen,))
62,177,265✔
1192
    return
62,177,265✔
1193
end
1194
function _deleteend!(a::Vector, delta::Integer)
19,288,183✔
1195
    delta = Int(delta)
2,869,983✔
1196
    len = length(a)
1,323,805,223✔
1197
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
1,323,805,223✔
1198
    newlen = len - delta
1,323,805,223✔
1199
    for i in newlen+1:len
1,368,402,705✔
1200
        @inbounds _unsetindex!(a, i)
2,147,483,647✔
1201
    end
2,147,483,647✔
1202
    setfield!(a, :size, (newlen,))
1,323,805,223✔
1203
    return
1,323,805,223✔
1204
end
1205
function _deleteat!(a::Vector, i::Integer, delta::Integer)
6,499,935✔
1206
    i = Int(i)
102,142✔
1207
    len = length(a)
6,499,935✔
1208
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
6,499,935✔
1209
    1 <= i <= len || throw(BoundsError(a, i))
6,499,938✔
1210
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
6,499,932✔
1211
    newa = a
102,127✔
1212
    if 2*i + delta <= len
6,499,932✔
1213
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
160,202✔
1214
        _deletebeg!(a, delta)
3,531,218✔
1215
    else
1216
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
8,610,545✔
1217
        _deleteend!(a, delta)
6,384,569✔
1218
    end
1219
    return
6,499,932✔
1220
end
1221
## Dequeue functionality ##
1222

1223
"""
1224
    push!(collection, items...) -> collection
1225

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

1229
# Examples
1230
```jldoctest
1231
julia> push!([1, 2, 3], 4, 5, 6)
1232
6-element Vector{Int64}:
1233
 1
1234
 2
1235
 3
1236
 4
1237
 5
1238
 6
1239
```
1240

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

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

1247
See also [`pushfirst!`](@ref).
1248
"""
1249
function push! end
1250

1251
function push!(a::Vector{T}, item) where T
53,212✔
1252
    # convert first so we don't grow the array if the assignment won't work
1253
    itemT = item isa T ? item : convert(T, item)::T
35,801,212✔
1254
    _growend!(a, 1)
2,147,483,647✔
1255
    @_safeindex a[length(a)] = itemT
2,147,483,647✔
1256
    return a
2,147,483,647✔
1257
end
1258

1259
# specialize and optimize the single argument case
1260
function push!(a::Vector{Any}, @nospecialize x)
6,353✔
1261
    _growend!(a, 1)
114,181,371✔
1262
    @_safeindex a[length(a)] = x
114,181,371✔
1263
    return a
114,181,371✔
1264
end
1265
function push!(a::Vector{Any}, @nospecialize x...)
16✔
1266
    @_terminates_locally_meta
17✔
1267
    na = length(a)
203,018✔
1268
    nx = length(x)
17✔
1269
    _growend!(a, nx)
203,018✔
1270
    @_safeindex for i = 1:nx
406,019✔
1271
        a[na+i] = x[i]
521,690✔
1272
    end
609,168✔
1273
    return a
203,018✔
1274
end
1275

1276
"""
1277
    append!(collection, collections...) -> collection.
1278

1279
For an ordered container `collection`, add the elements of each `collections`
1280
to the end of it.
1281

1282
!!! compat "Julia 1.6"
1283
    Specifying multiple collections to be appended requires at least Julia 1.6.
1284

1285
# Examples
1286
```jldoctest
1287
julia> append!([1], [2, 3])
1288
3-element Vector{Int64}:
1289
 1
1290
 2
1291
 3
1292

1293
julia> append!([1, 2, 3], [4, 5], [6])
1294
6-element Vector{Int64}:
1295
 1
1296
 2
1297
 3
1298
 4
1299
 5
1300
 6
1301
```
1302

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

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

1309
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1310
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1311
"""
1312
function append! end
1313

1314
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
7,946✔
1315
    items isa Tuple && (items = map(x -> convert(T, x), items))
43,704✔
1316
    n = length(items)
68,564,571✔
1317
    _growend!(a, n)
69,037,141✔
1318
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
106,959,236✔
1319
    return a
69,037,141✔
1320
end
1321

1322
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
74,117,456✔
1323
push!(a::AbstractVector, iter...) = append!(a, iter)
475,530✔
1324

1325
append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
7✔
1326

1327
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
22,410,931✔
1328
    n = Int(length(iter))::Int
22,642,980✔
1329
    i = lastindex(a)
30✔
1330
    sizehint!(a, length(a) + n; shrink=false)
22,410,933✔
1331
    for item in iter
36,647,068✔
1332
        push!(a, item)
44,732,933✔
1333
    end
44,964,208✔
1334
    a
11✔
1335
end
1336
function _append!(a::AbstractVector, ::IteratorSize, iter)
51,706,522✔
1337
    for item in iter
62,327,060✔
1338
        push!(a, item)
53,366,056✔
1339
    end
53,366,061✔
1340
    a
3✔
1341
end
1342

1343
"""
1344
    prepend!(a::Vector, collections...) -> collection
1345

1346
Insert the elements of each `collections` to the beginning of `a`.
1347

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

1351
!!! compat "Julia 1.6"
1352
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1353

1354
# Examples
1355
```jldoctest
1356
julia> prepend!([3], [1, 2])
1357
3-element Vector{Int64}:
1358
 1
1359
 2
1360
 3
1361

1362
julia> prepend!([6], [1, 2], [3, 4, 5])
1363
6-element Vector{Int64}:
1364
 1
1365
 2
1366
 3
1367
 4
1368
 5
1369
 6
1370
```
1371
"""
1372
function prepend! end
1373

1374
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
2,151✔
1375
    items isa Tuple && (items = map(x -> convert(T, x), items))
4,928✔
1376
    n = length(items)
5,871✔
1377
    _growbeg!(a, n)
11,169✔
1378
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1379
    # just the last n elements instead of all of them from the first
1380
    copyto!(a, 1, items, lastindex(items)-n+1, n)
11,164✔
1381
    return a
5,871✔
1382
end
1383

1384
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
368✔
1385
pushfirst!(a::Vector, iter...) = prepend!(a, iter)
7✔
1386

1387
prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
102,745✔
1388

1389
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
364✔
1390
    @_terminates_locally_meta
365✔
1391
    require_one_based_indexing(a)
365✔
1392
    n = Int(length(iter))::Int
365✔
1393
    sizehint!(a, length(a) + n; first=true, shrink=false)
365✔
1394
    n = 0
365✔
1395
    for item in iter
366✔
1396
        n += 1
603✔
1397
        pushfirst!(a, item)
603✔
1398
    end
599✔
1399
    reverse!(a, 1, n)
359✔
1400
    a
359✔
1401
end
1402
function _prepend!(a::Vector, ::IteratorSize, iter)
3✔
1403
    n = 0
3✔
1404
    for item in iter
5✔
1405
        n += 1
8✔
1406
        pushfirst!(a, item)
11✔
1407
    end
13✔
1408
    reverse!(a, 1, n)
2✔
1409
    a
2✔
1410
end
1411

1412
"""
1413
    resize!(a::Vector, n::Integer) -> Vector
1414

1415
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1416
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1417
guaranteed to be initialized.
1418

1419
# Examples
1420
```jldoctest
1421
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1422
3-element Vector{Int64}:
1423
 6
1424
 5
1425
 4
1426

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

1429
julia> length(a)
1430
8
1431

1432
julia> a[1:6]
1433
6-element Vector{Int64}:
1434
 6
1435
 5
1436
 4
1437
 3
1438
 2
1439
 1
1440
```
1441
"""
1442
function resize!(a::Vector, nl::Integer)
1,118,352,603✔
1443
    l = length(a)
1,169,074,580✔
1444
    if nl > l
1,169,074,580✔
1445
        _growend!(a, nl-l)
787,445,862✔
1446
    elseif nl != l
381,628,720✔
1447
        if nl < 0
96,621,415✔
1448
            _throw_argerror("new length must be ≥ 0")
2✔
1449
        end
1450
        _deleteend!(a, l-nl)
96,621,413✔
1451
    end
1452
    return a
1,169,074,578✔
1453
end
1454

1455
"""
1456
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1457

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

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

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

1471
See also [`resize!`](@ref).
1472

1473
# Notes on the performance model
1474

1475
For types that support `sizehint!`,
1476

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

1481
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1482
   `Base`.
1483

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

1486
!!! compat "Julia 1.11"
1487
    The `shrink` and `first` arguments were added in Julia 1.11.
1488
"""
1489
function sizehint! end
1490

1491
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
45,070,786✔
1492
    len = length(a)
22,534,637✔
1493
    ref = a.ref
22,534,637✔
1494
    mem = ref.mem
22,534,637✔
1495
    memlen = length(mem)
22,534,637✔
1496
    sz = max(Int(sz), len)
22,534,637✔
1497
    inc = sz - len
22,534,637✔
1498
    if sz <= memlen
22,534,637✔
1499
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1500
        if !shrink || memlen - sz <= div(memlen, 8)
19,518,474✔
1501
            return a
19,305,730✔
1502
        end
1503
        newmem = array_new_memory(mem, sz)
126,479✔
1504
        if first
104,559✔
1505
            newref = GenericMemoryRef(newmem, inc + 1)
×
1506
        else
1507
            newref = GenericMemoryRef(newmem)
104,559✔
1508
        end
1509
        unsafe_copyto!(newref, ref, len)
145,491✔
1510
        setfield!(a, :ref, newref)
104,559✔
1511
    elseif first
3,124,348✔
1512
        _growbeg!(a, inc)
720✔
1513
        newref = getfield(a, :ref)
360✔
1514
        newref = GenericMemoryRef(newref, inc + 1)
360✔
1515
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
360✔
1516
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
360✔
1517
    else # last
1518
        _growend!(a, inc)
3,123,988✔
1519
        setfield!(a, :size, (len,)) # undo the size change from _growend!
3,123,988✔
1520
    end
1521
    a
6,873✔
1522
end
1523

1524
# Fall-back implementation for non-shrinkable collections
1525
# avoid defining this the normal way to avoid avoid infinite recursion
1526
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
10✔
1527
    get(kwargs, :first, false)::Bool
211✔
1528
    get(kwargs, :shrink, true)::Bool
211✔
1529
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
211✔
1530
    sizehint!(a, sz)
211✔
1531
end
1532

1533
"""
1534
    pop!(collection) -> item
1535

1536
Remove an item in `collection` and return it. If `collection` is an
1537
ordered container, the last item is returned; for unordered containers,
1538
an arbitrary element is returned.
1539

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

1542
# Examples
1543
```jldoctest
1544
julia> A=[1, 2, 3]
1545
3-element Vector{Int64}:
1546
 1
1547
 2
1548
 3
1549

1550
julia> pop!(A)
1551
3
1552

1553
julia> A
1554
2-element Vector{Int64}:
1555
 1
1556
 2
1557

1558
julia> S = Set([1, 2])
1559
Set{Int64} with 2 elements:
1560
  2
1561
  1
1562

1563
julia> pop!(S)
1564
2
1565

1566
julia> S
1567
Set{Int64} with 1 element:
1568
  1
1569

1570
julia> pop!(Dict(1=>2))
1571
1 => 2
1572
```
1573
"""
1574
function pop!(a::Vector)
22,439✔
1575
    if isempty(a)
1,138,328,292✔
1576
        _throw_argerror("array must be non-empty")
1✔
1577
    end
1578
    item = a[end]
1,138,328,291✔
1579
    _deleteend!(a, 1)
1,138,328,291✔
1580
    return item
1,138,328,291✔
1581
end
1582

1583
"""
1584
    popat!(a::Vector, i::Integer, [default])
1585

1586
Remove the item at the given `i` and return it. Subsequent items
1587
are shifted to fill the resulting gap.
1588
When `i` is not a valid index for `a`, return `default`, or throw an error if
1589
`default` is not specified.
1590

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

1593
!!! compat "Julia 1.5"
1594
    This function is available as of Julia 1.5.
1595

1596
# Examples
1597
```jldoctest
1598
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1599
3
1600

1601
julia> a
1602
3-element Vector{Int64}:
1603
 4
1604
 2
1605
 1
1606

1607
julia> popat!(a, 4, missing)
1608
missing
1609

1610
julia> popat!(a, 4)
1611
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1612
[...]
1613
```
1614
"""
1615
function popat!(a::Vector, i::Integer)
4✔
1616
    x = a[i]
10✔
1617
    _deleteat!(a, i, 1)
4✔
1618
    x
4✔
1619
end
1620

1621
function popat!(a::Vector, i::Integer, default)
2✔
1622
    if 1 <= i <= length(a)
2✔
1623
        x = @inbounds a[i]
1✔
1624
        _deleteat!(a, i, 1)
1✔
1625
        x
1✔
1626
    else
1627
        default
1✔
1628
    end
1629
end
1630

1631
"""
1632
    pushfirst!(collection, items...) -> collection
1633

1634
Insert one or more `items` at the beginning of `collection`.
1635

1636
This function is called `unshift` in many other programming languages.
1637

1638
# Examples
1639
```jldoctest
1640
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1641
6-element Vector{Int64}:
1642
 5
1643
 6
1644
 1
1645
 2
1646
 3
1647
 4
1648
```
1649
"""
1650
function pushfirst!(a::Vector{T}, item) where T
410✔
1651
    item = item isa T ? item : convert(T, item)::T
2,865✔
1652
    _growbeg!(a, 1)
39,177✔
1653
    @_safeindex a[1] = item
37,378✔
1654
    return a
37,378✔
1655
end
1656

1657
# specialize and optimize the single argument case
1658
function pushfirst!(a::Vector{Any}, @nospecialize x)
13✔
1659
    _growbeg!(a, 1)
40,254,672✔
1660
    @_safeindex a[1] = x
39,473,678✔
1661
    return a
39,473,678✔
1662
end
1663
function pushfirst!(a::Vector{Any}, @nospecialize x...)
1✔
1664
    @_terminates_locally_meta
2✔
1665
    na = length(a)
2✔
1666
    nx = length(x)
2✔
1667
    _growbeg!(a, nx)
1,386✔
1668
    @_safeindex for i = 1:nx
1,384✔
1669
        a[i] = x[i]
1,388✔
1670
    end
2,083✔
1671
    return a
693✔
1672
end
1673

1674
"""
1675
    popfirst!(collection) -> item
1676

1677
Remove the first `item` from `collection`.
1678

1679
This function is called `shift` in many other programming languages.
1680

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

1683
# Examples
1684
```jldoctest
1685
julia> A = [1, 2, 3, 4, 5, 6]
1686
6-element Vector{Int64}:
1687
 1
1688
 2
1689
 3
1690
 4
1691
 5
1692
 6
1693

1694
julia> popfirst!(A)
1695
1
1696

1697
julia> A
1698
5-element Vector{Int64}:
1699
 2
1700
 3
1701
 4
1702
 5
1703
 6
1704
```
1705
"""
1706
function popfirst!(a::Vector)
321✔
1707
    if isempty(a)
62,036,595✔
1708
        _throw_argerror("array must be non-empty")
1✔
1709
    end
1710
    item = a[1]
62,036,594✔
1711
    _deletebeg!(a, 1)
62,036,594✔
1712
    return item
62,036,594✔
1713
end
1714

1715
"""
1716
    insert!(a::Vector, index::Integer, item)
1717

1718
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1719
the resulting `a`.
1720

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

1723
# Examples
1724
```jldoctest
1725
julia> insert!(Any[1:6;], 3, "here")
1726
7-element Vector{Any}:
1727
 1
1728
 2
1729
  "here"
1730
 3
1731
 4
1732
 5
1733
 6
1734
```
1735
"""
1736
function insert!(a::Array{T,1}, i::Integer, item) where T
299✔
1737
    @_noub_meta
1,367,959✔
1738
    # Throw convert error before changing the shape of the array
1739
    _item = item isa T ? item : convert(T, item)::T
1,367,965✔
1740
    _growat!(a, i, 1)
72,831,816✔
1741
    # :noub, because _growat! already did bound check
1742
    @inbounds a[i] = _item
72,831,814✔
1743
    return a
72,831,814✔
1744
end
1745

1746
"""
1747
    deleteat!(a::Vector, i::Integer)
1748

1749
Remove the item at the given `i` and return the modified `a`. Subsequent items
1750
are shifted to fill the resulting gap.
1751

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

1754
# Examples
1755
```jldoctest
1756
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1757
5-element Vector{Int64}:
1758
 6
1759
 4
1760
 3
1761
 2
1762
 1
1763
```
1764
"""
1765
function deleteat!(a::Vector, i::Integer)
404✔
1766
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,833✔
1767
    _deleteat!(a, i, 1)
6,300,035✔
1768
    return a
16,831✔
1769
end
1770

1771
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
34,081✔
1772
    if eltype(r) === Bool
75,706✔
1773
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1774
    else
1775
        n = length(a)
75,700✔
1776
        f = first(r)
75,700✔
1777
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
75,700✔
1778
        isempty(r) || _deleteat!(a, f, length(r))
376,872✔
1779
        return a
190,260✔
1780
    end
1781
end
1782

1783
"""
1784
    deleteat!(a::Vector, inds)
1785

1786
Remove the items at the indices given by `inds`, and return the modified `a`.
1787
Subsequent items are shifted to fill the resulting gap.
1788

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

1792
# Examples
1793
```jldoctest
1794
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1795
3-element Vector{Int64}:
1796
 5
1797
 3
1798
 1
1799

1800
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1801
3-element Vector{Int64}:
1802
 5
1803
 3
1804
 1
1805

1806
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1807
ERROR: ArgumentError: indices must be unique and sorted
1808
Stacktrace:
1809
[...]
1810
```
1811
"""
1812
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1813
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
88,397✔
1814

1815
struct Nowhere; end
1816
push!(::Nowhere, _) = nothing
×
1817
_growend!(::Nowhere, _) = nothing
×
1818

1819
function _push_deleted!(dltd, a::Vector, ind)
1820
    @_propagate_inbounds_meta
1,493,376✔
1821
    if isassigned(a, ind)
1,551,960✔
1822
        push!(dltd, a[ind])
1,551,959✔
1823
    else
1824
        _growend!(dltd, 1)
×
1825
    end
1826
end
1827

1828
function _copy_item!(a::Vector, p, q)
1829
    @_propagate_inbounds_meta
4,377,846✔
1830
    if isassigned(a, q)
4,409,707✔
1831
        a[p] = a[q]
4,409,706✔
1832
    else
1833
        _unsetindex!(a, p)
1✔
1834
    end
1835
end
1836

1837
function _deleteat!(a::Vector, inds, dltd=Nowhere())
88,417✔
1838
    n = length(a)
176,833✔
1839
    y = iterate(inds)
88,427✔
1840
    y === nothing && return a
88,417✔
1841
    (p, s) = y
35,477✔
1842
    checkbounds(a, p)
88,191✔
1843
    @inbounds _push_deleted!(dltd, a, p)
88,179✔
1844
    q = p+1
88,179✔
1845
    while true
1,551,960✔
1846
        y = iterate(inds, s)
1,551,971✔
1847
        y === nothing && break
1,551,960✔
1848
        (i,s) = y
1,457,905✔
1849
        if !(q <= i <= n)
1,463,783✔
1850
            if i < q
2✔
1851
                _throw_argerror("indices must be unique and sorted")
1✔
1852
            else
1853
                throw(BoundsError())
1✔
1854
            end
1855
        end
1856
        while q < i
2,887,475✔
1857
            @inbounds _copy_item!(a, p, q)
1,423,694✔
1858
            p += 1; q += 1
1,423,694✔
1859
        end
1,423,694✔
1860
        @inbounds _push_deleted!(dltd, a, i)
1,463,781✔
1861
        q = i+1
1,463,781✔
1862
    end
1,463,781✔
1863
    while q <= n
3,031,996✔
1864
        @inbounds _copy_item!(a, p, q)
2,943,819✔
1865
        p += 1; q += 1
2,943,819✔
1866
    end
2,943,819✔
1867
    _deleteend!(a, n-p+1)
1,551,958✔
1868
    return a
88,177✔
1869
end
1870

1871
# Simpler and more efficient version for logical indexing
1872
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1873
    n = length(a)
4,029✔
1874
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1875
    p = 1
4,024✔
1876
    for (q, i) in enumerate(inds)
8,047✔
1877
        @inbounds _copy_item!(a, p, q)
42,194✔
1878
        p += !i
42,194✔
1879
    end
80,365✔
1880
    _deleteend!(a, n-p+1)
21,353✔
1881
    return a
4,024✔
1882
end
1883

1884
const _default_splice = []
1885

1886
"""
1887
    splice!(a::Vector, index::Integer, [replacement]) -> item
1888

1889
Remove the item at the given index, and return the removed item.
1890
Subsequent items are shifted left to fill the resulting gap.
1891
If specified, replacement values from an ordered
1892
collection will be spliced in place of the removed item.
1893

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

1896
# Examples
1897
```jldoctest
1898
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1899
2
1900

1901
julia> A
1902
5-element Vector{Int64}:
1903
 6
1904
 5
1905
 4
1906
 3
1907
 1
1908

1909
julia> splice!(A, 5, -1)
1910
1
1911

1912
julia> A
1913
5-element Vector{Int64}:
1914
  6
1915
  5
1916
  4
1917
  3
1918
 -1
1919

1920
julia> splice!(A, 1, [-1, -2, -3])
1921
6
1922

1923
julia> A
1924
7-element Vector{Int64}:
1925
 -1
1926
 -2
1927
 -3
1928
  5
1929
  4
1930
  3
1931
 -1
1932
```
1933

1934
To insert `replacement` before an index `n` without removing any items, use
1935
`splice!(collection, n:n-1, replacement)`.
1936
"""
1937
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,695✔
1938
    v = a[i]
3,712✔
1939
    m = length(ins)
3,426✔
1940
    if m == 0
3,426✔
1941
        _deleteat!(a, i, 1)
551✔
1942
    elseif m == 1
2,875✔
1943
        a[i] = only(ins)
266✔
1944
    else
1945
        _growat!(a, i, m-1)
2,609✔
1946
        k = 1
2,609✔
1947
        for x in ins
2,609✔
1948
            a[i+k-1] = x
332,874✔
1949
            k += 1
332,874✔
1950
        end
332,874✔
1951
    end
1952
    return v
3,426✔
1953
end
1954

1955
"""
1956
    splice!(a::Vector, indices, [replacement]) -> items
1957

1958
Remove items at specified indices, and return a collection containing
1959
the removed items.
1960
Subsequent items are shifted left to fill the resulting gaps.
1961
If specified, replacement values from an ordered collection will be spliced in
1962
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
1963

1964
To insert `replacement` before an index `n` without removing any items, use
1965
`splice!(collection, n:n-1, replacement)`.
1966

1967
$(_DOCS_ALIASING_WARNING)
1968

1969
!!! compat "Julia 1.5"
1970
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1971

1972
!!! compat "Julia 1.8"
1973
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1974

1975
# Examples
1976
```jldoctest
1977
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
1978
Int64[]
1979

1980
julia> A
1981
8-element Vector{Int64}:
1982
 -1
1983
 -2
1984
 -3
1985
  2
1986
  5
1987
  4
1988
  3
1989
 -1
1990
```
1991
"""
1992
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
17,954,551✔
1993
    v = a[r]
18,024,781✔
1994
    m = length(ins)
71,650✔
1995
    if m == 0
71,650✔
1996
        deleteat!(a, r)
74,059✔
1997
        return v
37,090✔
1998
    end
1999

2000
    n = length(a)
17,883,523✔
2001
    f = first(r)
17,883,523✔
2002
    l = last(r)
17,883,523✔
2003
    d = length(r)
17,883,523✔
2004

2005
    if m < d
17,883,523✔
2006
        delta = d - m
12,699✔
2007
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
19,182✔
2008
    elseif m > d
17,870,824✔
2009
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
17,870,709✔
2010
    end
2011

2012
    k = 1
34,560✔
2013
    for x in ins
17,895,029✔
2014
        a[f+k-1] = x
58,914,287✔
2015
        k += 1
57,572,386✔
2016
    end
76,763,144✔
2017
    return v
17,883,523✔
2018
end
2019

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

2022
function empty!(a::Vector)
54✔
2023
    _deleteend!(a, length(a))
93,122,674✔
2024
    return a
82,314,977✔
2025
end
2026

2027
# use memcmp for cmp on byte arrays
2028
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
2029
    aref = a.ref
3✔
2030
    bref = b.ref
3✔
2031
    ta = @_gc_preserve_begin aref
3✔
2032
    tb = @_gc_preserve_begin bref
3✔
2033
    pa = unsafe_convert(Ptr{Cvoid}, aref)
3✔
2034
    pb = unsafe_convert(Ptr{Cvoid}, bref)
3✔
2035
    c = memcmp(pa, pb, min(length(a),length(b)))
3✔
2036
    @_gc_preserve_end ta
3✔
2037
    @_gc_preserve_end tb
3✔
2038
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
2039
end
2040

2041
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2042
# use memcmp for == on bit integer types
2043
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,291✔
2044
    if size(a) == size(b)
3,241✔
2045
        aref = a.ref
1,643✔
2046
        bref = b.ref
1,643✔
2047
        ta = @_gc_preserve_begin aref
1,643✔
2048
        tb = @_gc_preserve_begin bref
1,643✔
2049
        pa = unsafe_convert(Ptr{Cvoid}, aref)
1,643✔
2050
        pb = unsafe_convert(Ptr{Cvoid}, bref)
1,643✔
2051
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
1,643✔
2052
        @_gc_preserve_end ta
1,643✔
2053
        @_gc_preserve_end tb
1,643✔
2054
        return c == 0
1,643✔
2055
    else
2056
        return false
×
2057
    end
2058
end
2059

2060
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
5,427✔
2061
    len = length(a)
58,774✔
2062
    if len == length(b)
58,774✔
2063
        aref = a.ref
58,650✔
2064
        bref = b.ref
25,741✔
2065
        ta = @_gc_preserve_begin aref
58,650✔
2066
        tb = @_gc_preserve_begin bref
58,650✔
2067
        T = eltype(Arr)
13,627✔
2068
        pa = unsafe_convert(Ptr{T}, aref)
58,650✔
2069
        pb = unsafe_convert(Ptr{T}, bref)
58,650✔
2070
        c = memcmp(pa, pb, sizeof(T) * len)
58,650✔
2071
        @_gc_preserve_end ta
58,650✔
2072
        @_gc_preserve_end tb
58,650✔
2073
        return c == 0
58,650✔
2074
    else
2075
        return false
124✔
2076
    end
2077
end
2078

2079
"""
2080
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2081

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

2085
# Examples
2086
```jldoctest
2087
julia> A = Vector(1:5)
2088
5-element Vector{Int64}:
2089
 1
2090
 2
2091
 3
2092
 4
2093
 5
2094

2095
julia> reverse(A)
2096
5-element Vector{Int64}:
2097
 5
2098
 4
2099
 3
2100
 2
2101
 1
2102

2103
julia> reverse(A, 1, 4)
2104
5-element Vector{Int64}:
2105
 4
2106
 3
2107
 2
2108
 1
2109
 5
2110

2111
julia> reverse(A, 3, 5)
2112
5-element Vector{Int64}:
2113
 1
2114
 2
2115
 5
2116
 4
2117
 3
2118
```
2119
"""
2120
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
7,526✔
2121
    s, n = Int(start), Int(stop)
915✔
2122
    B = similar(A)
14,782✔
2123
    for i = firstindex(A):s-1
7,527✔
2124
        B[i] = A[i]
1,684✔
2125
    end
3,078✔
2126
    for i = s:n
7,536✔
2127
        B[i] = A[n+s-i]
288,912✔
2128
    end
570,308✔
2129
    for i = n+1:lastindex(A)
14,762✔
2130
        B[i] = A[i]
1,690✔
2131
    end
3,090✔
2132
    return B
7,526✔
2133
end
2134

2135
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2136
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2137
    @eval begin
2138
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
135,352,926✔
2139
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
11,622✔
2140
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2141
        function $_f(A::AbstractVector, dim::Integer)
2142
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
10✔
2143
            return $_f(A, :)
3✔
2144
        end
2145
    end
2146
end
2147

2148
function reverseind(a::AbstractVector, i::Integer)
3✔
2149
    li = LinearIndices(a)
3✔
2150
    first(li) + last(li) - i
3✔
2151
end
2152

2153
# This implementation of `midpoint` is performance-optimized but safe
2154
# only if `lo <= hi`.
2155
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
15,652,699✔
2156
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2157

2158
"""
2159
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2160

2161
In-place version of [`reverse`](@ref).
2162

2163
# Examples
2164
```jldoctest
2165
julia> A = Vector(1:5)
2166
5-element Vector{Int64}:
2167
 1
2168
 2
2169
 3
2170
 4
2171
 5
2172

2173
julia> reverse!(A);
2174

2175
julia> A
2176
5-element Vector{Int64}:
2177
 5
2178
 4
2179
 3
2180
 2
2181
 1
2182
```
2183
"""
2184
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
176,495✔
2185
    s, n = Int(start), Int(stop)
142,209✔
2186
    if n > s # non-empty and non-trivial
176,492✔
2187
        liv = LinearIndices(v)
164,795✔
2188
        if !(first(liv) ≤ s ≤ last(liv))
164,795✔
2189
            throw(BoundsError(v, s))
3✔
2190
        elseif !(first(liv) ≤ n ≤ last(liv))
164,792✔
2191
            throw(BoundsError(v, n))
1✔
2192
        end
2193
        r = n
132,221✔
2194
        @inbounds for i in s:midpoint(s, n-1)
164,791✔
2195
            v[i], v[r] = v[r], v[i]
9,824,860✔
2196
            r -= 1
9,824,860✔
2197
        end
19,484,929✔
2198
    end
2199
    return v
176,488✔
2200
end
2201

2202
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2203

2204
vcat() = Vector{Any}()
10,429✔
2205
hcat() = Vector{Any}()
1✔
2206

2207
function hcat(V::Vector{T}...) where T
62✔
2208
    height = length(V[1])
570✔
2209
    for j = 2:length(V)
570✔
2210
        if length(V[j]) != height
636✔
2211
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2212
        end
2213
    end
733✔
2214
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
569✔
2215
end
2216
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
4✔
2217

2218
function vcat(arrays::Vector{T}...) where T
32,340✔
2219
    n = 0
3,297✔
2220
    for a in arrays
32,340✔
2221
        n += length(a)
2,065,115✔
2222
    end
2,097,450✔
2223
    arr = Vector{T}(undef, n)
64,660✔
2224
    nd = 1
3,297✔
2225
    for a in arrays
32,340✔
2226
        na = length(a)
2,065,115✔
2227
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,065,115✔
2228
        unsafe_copyto!(arr, nd, a, 1, na)
4,127,118✔
2229
        nd += na
2,065,115✔
2230
    end
2,097,450✔
2231
    return arr
32,340✔
2232
end
2233
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
35✔
2234

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

2237
## find ##
2238

2239
"""
2240
    findnext(A, i)
2241

2242
Find the next index after or including `i` of a `true` element of `A`,
2243
or `nothing` if not found.
2244

2245
Indices are of the same type as those returned by [`keys(A)`](@ref)
2246
and [`pairs(A)`](@ref).
2247

2248
# Examples
2249
```jldoctest
2250
julia> A = [false, false, true, false]
2251
4-element Vector{Bool}:
2252
 0
2253
 0
2254
 1
2255
 0
2256

2257
julia> findnext(A, 1)
2258
3
2259

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

2262
julia> A = [false false; true false]
2263
2×2 Matrix{Bool}:
2264
 0  0
2265
 1  0
2266

2267
julia> findnext(A, CartesianIndex(1, 1))
2268
CartesianIndex(2, 1)
2269
```
2270
"""
2271
findnext(A, start) = findnext(identity, A, start)
43,420✔
2272

2273
"""
2274
    findfirst(A)
2275

2276
Return the index or key of the first `true` value in `A`.
2277
Return `nothing` if no such value is found.
2278
To search for other kinds of values, pass a predicate as the first argument.
2279

2280
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2281
and [`pairs(A)`](@ref).
2282

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

2285
# Examples
2286
```jldoctest
2287
julia> A = [false, false, true, false]
2288
4-element Vector{Bool}:
2289
 0
2290
 0
2291
 1
2292
 0
2293

2294
julia> findfirst(A)
2295
3
2296

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

2299
julia> A = [false false; true false]
2300
2×2 Matrix{Bool}:
2301
 0  0
2302
 1  0
2303

2304
julia> findfirst(A)
2305
CartesianIndex(2, 1)
2306
```
2307
"""
2308
findfirst(A) = findfirst(identity, A)
2✔
2309

2310
# Needed for bootstrap, and allows defining only an optimized findnext method
2311
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
12,064✔
2312

2313
"""
2314
    findnext(predicate::Function, A, i)
2315

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

2321
Indices are of the same type as those returned by [`keys(A)`](@ref)
2322
and [`pairs(A)`](@ref).
2323

2324
# Examples
2325
```jldoctest
2326
julia> A = [1, 4, 2, 2];
2327

2328
julia> findnext(isodd, A, 1)
2329
1
2330

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

2333
julia> A = [1 4; 2 2];
2334

2335
julia> findnext(isodd, A, CartesianIndex(1, 1))
2336
CartesianIndex(1, 1)
2337

2338
julia> findnext(isspace, "a b c", 3)
2339
4
2340
```
2341
"""
2342
function findnext(testf::Function, A, start)
19,541✔
2343
    i = oftype(first(keys(A)), start)
45,135✔
2344
    l = last(keys(A))
74,138,972✔
2345
    i > l && return nothing
74,138,972✔
2346
    while true
157,029,968✔
2347
        testf(A[i]) && return i
157,050,426✔
2348
        i == l && break
150,676,171✔
2349
        # nextind(A, l) can throw/overflow
2350
        i = nextind(A, i)
146,737,840✔
2351
    end
146,737,821✔
2352
    return nothing
3,938,326✔
2353
end
2354

2355
"""
2356
    findfirst(predicate::Function, A)
2357

2358
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2359
Return `nothing` if there is no such element.
2360

2361
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2362
and [`pairs(A)`](@ref).
2363

2364
# Examples
2365
```jldoctest
2366
julia> A = [1, 4, 2, 2]
2367
4-element Vector{Int64}:
2368
 1
2369
 4
2370
 2
2371
 2
2372

2373
julia> findfirst(iseven, A)
2374
2
2375

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

2378
julia> findfirst(isequal(4), A)
2379
2
2380

2381
julia> A = [1 4; 2 2]
2382
2×2 Matrix{Int64}:
2383
 1  4
2384
 2  2
2385

2386
julia> findfirst(iseven, A)
2387
CartesianIndex(2, 1)
2388
```
2389
"""
2390
function findfirst(testf::Function, A)
15✔
2391
    for (i, a) in pairs(A)
22✔
2392
        testf(a) && return i
14✔
2393
    end
11✔
2394
    return nothing
8✔
2395
end
2396

2397
# Needed for bootstrap, and allows defining only an optimized findnext method
2398
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
231,991,314✔
2399
    findnext(testf, A, first(keys(A)))
2400

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

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

2407
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2408
    isempty(r) && return nothing
6✔
2409
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2410
    d = convert(S, p.x - first(r))::S
3✔
2411
    iszero(d % step(r)) || return nothing
3✔
2412
    return d ÷ step(r) + 1
3✔
2413
end
2414

2415
"""
2416
    findprev(A, i)
2417

2418
Find the previous index before or including `i` of a `true` element of `A`,
2419
or `nothing` if not found.
2420

2421
Indices are of the same type as those returned by [`keys(A)`](@ref)
2422
and [`pairs(A)`](@ref).
2423

2424
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2425

2426
# Examples
2427
```jldoctest
2428
julia> A = [false, false, true, true]
2429
4-element Vector{Bool}:
2430
 0
2431
 0
2432
 1
2433
 1
2434

2435
julia> findprev(A, 3)
2436
3
2437

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

2440
julia> A = [false false; true true]
2441
2×2 Matrix{Bool}:
2442
 0  0
2443
 1  1
2444

2445
julia> findprev(A, CartesianIndex(2, 1))
2446
CartesianIndex(2, 1)
2447
```
2448
"""
2449
findprev(A, start) = findprev(identity, A, start)
8,326✔
2450

2451
"""
2452
    findlast(A)
2453

2454
Return the index or key of the last `true` value in `A`.
2455
Return `nothing` if there is no `true` value in `A`.
2456

2457
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2458
and [`pairs(A)`](@ref).
2459

2460
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2461

2462
# Examples
2463
```jldoctest
2464
julia> A = [true, false, true, false]
2465
4-element Vector{Bool}:
2466
 1
2467
 0
2468
 1
2469
 0
2470

2471
julia> findlast(A)
2472
3
2473

2474
julia> A = falses(2,2);
2475

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

2478
julia> A = [true false; true false]
2479
2×2 Matrix{Bool}:
2480
 1  0
2481
 1  0
2482

2483
julia> findlast(A)
2484
CartesianIndex(2, 1)
2485
```
2486
"""
2487
findlast(A) = findlast(identity, A)
23✔
2488

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

2492
"""
2493
    findprev(predicate::Function, A, i)
2494

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

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

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

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

2514
julia> findprev(isodd, A, 3)
2515
3
2516

2517
julia> A = [4 6; 1 2]
2518
2×2 Matrix{Int64}:
2519
 4  6
2520
 1  2
2521

2522
julia> findprev(isodd, A, CartesianIndex(1, 2))
2523
CartesianIndex(2, 1)
2524

2525
julia> findprev(isspace, "a b c", 3)
2526
2
2527
```
2528
"""
2529
function findprev(testf::Function, A, start)
273✔
2530
    f = first(keys(A))
36,951✔
2531
    i = oftype(f, start)
36,962✔
2532
    i < f && return nothing
40,992✔
2533
    while true
306,459✔
2534
        testf(A[i]) && return i
306,654✔
2535
        i == f && break
267,895✔
2536
        # prevind(A, f) can throw/underflow
2537
        i = prevind(A, i)
265,522✔
2538
    end
265,494✔
2539
    return nothing
2,370✔
2540
end
2541

2542
"""
2543
    findlast(predicate::Function, A)
2544

2545
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2546
Return `nothing` if there is no such element.
2547

2548
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2549
and [`pairs(A)`](@ref).
2550

2551
# Examples
2552
```jldoctest
2553
julia> A = [1, 2, 3, 4]
2554
4-element Vector{Int64}:
2555
 1
2556
 2
2557
 3
2558
 4
2559

2560
julia> findlast(isodd, A)
2561
3
2562

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

2565
julia> A = [1 2; 3 4]
2566
2×2 Matrix{Int64}:
2567
 1  2
2568
 3  4
2569

2570
julia> findlast(isodd, A)
2571
CartesianIndex(2, 1)
2572
```
2573
"""
2574
function findlast(testf::Function, A)
3✔
2575
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2576
        testf(a) && return i
6✔
2577
    end
6✔
2578
    return nothing
2✔
2579
end
2580

2581
# Needed for bootstrap, and allows defining only an optimized findprev method
2582
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
14,776✔
2583
    findprev(testf, A, last(keys(A)))
2584

2585
"""
2586
    findall(f::Function, A)
2587

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

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

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

2602
julia> findall(isodd, x)
2603
2-element Vector{Int64}:
2604
 1
2605
 2
2606

2607
julia> A = [1 2 0; 3 4 0]
2608
2×3 Matrix{Int64}:
2609
 1  2  0
2610
 3  4  0
2611
julia> findall(isodd, A)
2612
2-element Vector{CartesianIndex{2}}:
2613
 CartesianIndex(1, 1)
2614
 CartesianIndex(2, 1)
2615

2616
julia> findall(!iszero, A)
2617
4-element Vector{CartesianIndex{2}}:
2618
 CartesianIndex(1, 1)
2619
 CartesianIndex(2, 1)
2620
 CartesianIndex(1, 2)
2621
 CartesianIndex(2, 2)
2622

2623
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2624
Dict{Symbol, Int64} with 3 entries:
2625
  :A => 10
2626
  :B => -1
2627
  :C => 0
2628

2629
julia> findall(≥(0), d)
2630
2-element Vector{Symbol}:
2631
 :A
2632
 :C
2633

2634
```
2635
"""
2636
function findall(testf::Function, A)
26✔
2637
    gen = (first(p) for p in pairs(A) if testf(last(p)))
59✔
2638
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
59✔
2639
end
2640

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

2645
"""
2646
    findall(A)
2647

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

2652
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2653
and [`pairs(A)`](@ref).
2654

2655
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2656

2657
# Examples
2658
```jldoctest
2659
julia> A = [true, false, false, true]
2660
4-element Vector{Bool}:
2661
 1
2662
 0
2663
 0
2664
 1
2665

2666
julia> findall(A)
2667
2-element Vector{Int64}:
2668
 1
2669
 4
2670

2671
julia> A = [true false; false true]
2672
2×2 Matrix{Bool}:
2673
 1  0
2674
 0  1
2675

2676
julia> findall(A)
2677
2-element Vector{CartesianIndex{2}}:
2678
 CartesianIndex(1, 1)
2679
 CartesianIndex(2, 2)
2680

2681
julia> findall(falses(3))
2682
Int64[]
2683
```
2684
"""
2685
function findall(A)
4✔
2686
    collect(first(p) for p in pairs(A) if last(p))
4✔
2687
end
2688

2689
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2690
function findall(A::AbstractArray{Bool})
823✔
2691
    n = count(A)
3,423✔
2692
    I = Vector{eltype(keys(A))}(undef, n)
6,462✔
2693
    cnt = 1
3,418✔
2694
    for (i,a) in pairs(A)
6,828✔
2695
        if a
182,188✔
2696
            I[cnt] = i
105,034✔
2697
            cnt += 1
105,034✔
2698
        end
2699
    end
360,963✔
2700
    I
3,418✔
2701
end
2702

2703
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2704
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2705
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2706

2707
# similar to Matlab's ismember
2708
"""
2709
    indexin(a, b)
2710

2711
Return an array containing the first index in `b` for
2712
each value in `a` that is a member of `b`. The output
2713
array contains `nothing` wherever `a` is not a member of `b`.
2714

2715
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2716

2717
# Examples
2718
```jldoctest
2719
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2720

2721
julia> b = ['a', 'b', 'c'];
2722

2723
julia> indexin(a, b)
2724
6-element Vector{Union{Nothing, Int64}}:
2725
 1
2726
 2
2727
 3
2728
 2
2729
  nothing
2730
 1
2731

2732
julia> indexin(b, a)
2733
3-element Vector{Union{Nothing, Int64}}:
2734
 1
2735
 2
2736
 3
2737
```
2738
"""
2739
function indexin(a, b::AbstractArray)
7✔
2740
    inds = keys(b)
7✔
2741
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2742
    for (val, ind) in zip(b, inds)
14✔
2743
        get!(bdict, val, ind)
30✔
2744
    end
53✔
2745
    return Union{eltype(inds), Nothing}[
7✔
2746
        get(bdict, i, nothing) for i in a
2747
    ]
2748
end
2749

2750
function _findin(a::Union{AbstractArray, Tuple}, b)
375✔
2751
    ind  = Vector{eltype(keys(a))}()
561✔
2752
    bset = Set(b)
377✔
2753
    @inbounds for (i,ai) in pairs(a)
606✔
2754
        ai in bset && push!(ind, i)
90,559✔
2755
    end
180,565✔
2756
    ind
375✔
2757
end
2758

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

2804
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2805
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2806
        return _sortedfindin(x, pred.x)
9✔
2807
    else
2808
        return _findin(x, pred.x)
6✔
2809
    end
2810
end
2811
# issorted fails for some element types so the method above has to be restricted
2812
# to element with isless/< defined.
2813
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
373✔
2814
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2815

2816
# Copying subregions
2817
function indcopy(sz::Dims, I::Vector)
1✔
2818
    n = length(I)
1✔
2819
    s = sz[n]
1✔
2820
    for i = n+1:length(sz)
2✔
2821
        s *= sz[i]
×
2822
    end
×
2823
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2824
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2825
    dst, src
1✔
2826
end
2827

2828
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2829
    n = length(I)
1✔
2830
    s = sz[n]
1✔
2831
    for i = n+1:length(sz)
1✔
2832
        s *= sz[i]
×
2833
    end
×
2834
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2835
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2836
    dst, src
1✔
2837
end
2838

2839
## Filter ##
2840

2841
"""
2842
    filter(f, a)
2843

2844
Return a copy of collection `a`, removing elements for which `f` is `false`.
2845
The function `f` is passed one argument.
2846

2847
!!! compat "Julia 1.4"
2848
    Support for `a` as a tuple requires at least Julia 1.4.
2849

2850
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2851

2852
# Examples
2853
```jldoctest
2854
julia> a = 1:10
2855
1:10
2856

2857
julia> filter(isodd, a)
2858
5-element Vector{Int64}:
2859
 1
2860
 3
2861
 5
2862
 7
2863
 9
2864
```
2865
"""
2866
function filter(f, a::Array{T, N}) where {T, N}
13,811✔
2867
    j = 1
2,149✔
2868
    b = Vector{T}(undef, length(a))
27,466✔
2869
    for ai in a
13,811✔
2870
        @inbounds b[j] = ai
1,996,491✔
2871
        j = ifelse(f(ai)::Bool, j+1, j)
1,997,662✔
2872
    end
1,996,491✔
2873
    resize!(b, j-1)
13,811✔
2874
    sizehint!(b, length(b))
13,811✔
2875
    b
2,149✔
2876
end
2877

2878
function filter(f, a::AbstractArray)
457✔
2879
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
457✔
2880

2881
    j = 1
457✔
2882
    idxs = Vector{Int}(undef, length(a))
752✔
2883
    for idx in eachindex(a)
460✔
2884
        @inbounds idxs[j] = idx
103,549✔
2885
        ai = @inbounds a[idx]
103,549✔
2886
        j = ifelse(f(ai)::Bool, j+1, j)
105,082✔
2887
    end
206,802✔
2888
    resize!(idxs, j-1)
456✔
2889
    res = a[idxs]
456✔
2890
    empty!(idxs)
4,200✔
2891
    sizehint!(idxs, 0)
456✔
2892
    return res
456✔
2893
end
2894

2895
"""
2896
    filter!(f, a)
2897

2898
Update collection `a`, removing elements for which `f` is `false`.
2899
The function `f` is passed one argument.
2900

2901
# Examples
2902
```jldoctest
2903
julia> filter!(isodd, Vector(1:10))
2904
5-element Vector{Int64}:
2905
 1
2906
 3
2907
 5
2908
 7
2909
 9
2910
```
2911
"""
2912
function filter!(f, a::AbstractVector)
974,483✔
2913
    j = firstindex(a)
971✔
2914
    for ai in a
97,861,586✔
2915
        @inbounds a[j] = ai
115,158,200✔
2916
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
115,188,571✔
2917
    end
115,158,209✔
2918
    j > lastindex(a) && return a
97,861,585✔
2919
    if a isa Vector
389✔
2920
        resize!(a, j-1)
74,779✔
2921
        sizehint!(a, j-1)
74,779✔
2922
    else
2923
        deleteat!(a, j:lastindex(a))
1✔
2924
    end
2925
    return a
74,780✔
2926
end
2927

2928
"""
2929
    filter(f)
2930

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

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

2937
# Examples
2938
```jldoctest
2939
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2940
(1, 2, 4, 6)
2941

2942
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2943
3-element Vector{Vector{Int64}}:
2944
 [2]
2945
 [2, 4]
2946
 [4]
2947
```
2948
!!! compat "Julia 1.9"
2949
    This method requires at least Julia 1.9.
2950
"""
2951
function filter(f)
1✔
2952
    Fix1(filter, f)
1✔
2953
end
2954

2955
"""
2956
    keepat!(a::Vector, inds)
2957
    keepat!(a::BitVector, inds)
2958

2959
Remove the items at all the indices which are not given by `inds`,
2960
and return the modified `a`.
2961
Items which are kept are shifted to fill the resulting gaps.
2962

2963
$(_DOCS_ALIASING_WARNING)
2964

2965
`inds` must be an iterator of sorted and unique integer indices.
2966
See also [`deleteat!`](@ref).
2967

2968
!!! compat "Julia 1.7"
2969
    This function is available as of Julia 1.7.
2970

2971
# Examples
2972
```jldoctest
2973
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
2974
3-element Vector{Int64}:
2975
 6
2976
 4
2977
 2
2978
```
2979
"""
2980
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
2981

2982
"""
2983
    keepat!(a::Vector, m::AbstractVector{Bool})
2984
    keepat!(a::BitVector, m::AbstractVector{Bool})
2985

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

2990
# Examples
2991
```jldoctest
2992
julia> a = [:a, :b, :c];
2993

2994
julia> keepat!(a, [true, false, true])
2995
2-element Vector{Symbol}:
2996
 :a
2997
 :c
2998

2999
julia> a
3000
2-element Vector{Symbol}:
3001
 :a
3002
 :c
3003
```
3004
"""
3005
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
3006

3007
# set-like operators for vectors
3008
# These are moderately efficient, preserve order, and remove dupes.
3009

3010
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
18,120✔
3011
    # P, U force specialization
3012
    if pred(x, state)
32,799✔
3013
        update!(state, x)
8,181✔
3014
        true
3015
    else
3016
        false
3017
    end
3018
end
3019

3020
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
293✔
3021
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
1,141✔
3022

3023
function _grow!(pred!, v::AbstractVector, itrs)
110✔
3024
    filter!(pred!, v) # uniquify v
320✔
3025
    for itr in itrs
320✔
3026
        mapfilter(pred!, push!, itr, v)
627✔
3027
    end
927✔
3028
    return v
320✔
3029
end
3030

3031
union!(v::AbstractVector{T}, itrs...) where {T} =
305✔
3032
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3033

3034
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
3035
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3036

3037
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
2✔
3038
    seen = Set{eltype(v)}()
6✔
3039
    filter!(_grow_filter!(seen), v)
6✔
3040
    shrinker!(seen, itrs...)
6✔
3041
    filter!(in(seen), v)
6✔
3042
end
3043

3044
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
3045
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
3046

3047
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
1,109✔
3048

3049
function _shrink(shrinker!::F, itr, itrs) where F
1,011✔
3050
    T = promote_eltype(itr, itrs...)
913✔
3051
    keep = shrinker!(Set{T}(itr), itrs...)
2,071✔
3052
    vectorfilter(T, _shrink_filter!(keep), itr)
1,050✔
3053
end
3054

3055
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
511✔
3056
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
541✔
3057

3058
function intersect(v::AbstractVector, r::AbstractRange)
7✔
3059
    T = promote_eltype(v, r)
11✔
3060
    common = Iterators.filter(in(r), v)
59✔
3061
    seen = Set{T}(common)
59✔
3062
    return vectorfilter(T, _shrink_filter!(seen), common)
59✔
3063
end
3064
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
3065

3066
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3067
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
3,852✔
3068
    if i isa Bool # Not via dispatch to avoid ambiguities
29,403,622✔
3069
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3070
    else
3071
        _getindex(v, i)
486,904,198✔
3072
    end
3073
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