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

JuliaLang / julia / #37798

05 Jun 2024 07:57AM UTC coverage: 83.152% (-3.8%) from 86.908%
#37798

push

local

web-flow
Use the public `wait()` in the `errormonitor()` docstring (#54650)

72847 of 87607 relevant lines covered (83.15%)

14515294.14 hits per line

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

81.26
/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,482✔
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}()
27,244,000✔
159
function vect(X::T...) where T
11,103✔
160
    @_terminates_locally_meta
37,668✔
161
    vec = Vector{T}(undef, length(X))
1,271,451✔
162
    @_safeindex for i = 1:length(X)
126,351✔
163
        vec[i] = X[i]
1,385,430✔
164
    end
329,605✔
165
    return vec
81,395✔
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...)
744✔
184
    T = promote_typeof(X...)
3,914✔
185
    return T[X...]
4,086✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
10,482✔
190
    d < 1 && error("arraysize: dimension out of range")
65,330,986✔
191
    sz = getfield(a, :size)
65,449,373✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
97,634,135✔
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))
8,798✔
199

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

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

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

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

216
function _unsetindex!(A::Array, i::Int)
217
    @inline
2,384,194✔
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

223

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

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

237
function isassigned(a::Array, i::Int...)
110,213✔
238
    @inline
445,289✔
239
    @_noub_if_noinbounds_meta
445,289✔
240
    @boundscheck checkbounds(Bool, a, i...) || return false
445,301✔
241
    ii = _sub2ind(size(a), i...)
445,281✔
242
    return @inbounds isassigned(memoryref(a.ref, ii, false))
445,281✔
243
end
244

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

252

253
## copy ##
254

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

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

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

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

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

278
The `unsafe` prefix on this function indicates that no validation is performed to ensure
279
that n is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
280
the same manner as C.
281
"""
282
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
283
    n == 0 && return dest
10,844,137✔
284
    unsafe_copyto!(GenericMemoryRef(dest.ref, doffs), GenericMemoryRef(src.ref, soffs), n)
13,762,046✔
285
    return dest
6,881,026✔
286
end
287

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

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

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

301
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
11✔
302
    n == 0 && return dest
131,815,281✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
103,225,055✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
103,225,073✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
103,225,036✔
306
    @inbounds let dest = GenericMemoryRef(dest isa Array ? getfield(dest, :ref) : dest, doffs),
103,225,041✔
307
                  src = GenericMemoryRef(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
206,450,026✔
309
    end
310
    return dest
103,224,789✔
311
end
312

313

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

319
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
33,851✔
320

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

324
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
325
# for bootstrapping purposes.
326
function fill!(dest::Array{T}, x) where T
945✔
327
    xT = x isa T ? x : convert(T, x)::T
252,187✔
328
    for i in eachindex(dest)
715,311,507✔
329
        @inbounds dest[i] = xT
2,147,483,647✔
330
    end
2,147,483,647✔
331
    return dest
715,311,507✔
332
end
333

334
"""
335
    copy(x)
336

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

341
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
342
"""
343
copy
344

345
@eval function copy(a::Array{T}) where {T}
5,476✔
346
    # `jl_genericmemory_copy_slice` only throws when the size exceeds the max allocation
347
    # size, but since we're copying an existing array, we're guaranteed that this will not happen.
348
    @_nothrow_meta
130,167✔
349
    ref = a.ref
147,699,843✔
350
    newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a))
147,699,845✔
351
    return $(Expr(:new, :(typeof(a)), :(Core.memoryref(newmem)), :(a.size)))
147,699,731✔
352
end
353

354
## Constructors ##
355

356
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
232,918✔
357
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
7,143✔
358
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
15,205✔
359
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
25,011✔
360
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
3,586,575✔
361
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
87,823,737✔
362
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
350✔
363

364
# T[x...] constructs Array{T,1}
365
"""
366
    getindex(type[, elements...])
367

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

371
# Examples
372
```jldoctest
373
julia> Int8[1, 2, 3]
374
3-element Vector{Int8}:
375
 1
376
 2
377
 3
378

379
julia> getindex(Int8, 1, 2, 3)
380
3-element Vector{Int8}:
381
 1
382
 2
383
 3
384
```
385
"""
386
function getindex(::Type{T}, vals...) where T
3,902✔
387
    @inline
98,675✔
388
    @_effect_free_terminates_locally_meta
98,675✔
389
    a = Vector{T}(undef, length(vals))
776,266,471✔
390
    if vals isa NTuple
98,706✔
391
        @_safeindex for i in 1:length(vals)
94,140✔
392
            a[i] = vals[i]
55,017,253✔
393
        end
211,543✔
394
    else
395
        # use afoldl to avoid type instability inside loop
396
        afoldl(1, vals...) do i, v
6,806✔
397
            @inbounds a[i] = v
18,874✔
398
            return i + 1
18,864✔
399
        end
400
    end
401
    return a
100,870✔
402
end
403

404
function getindex(::Type{Any}, @nospecialize vals...)
19,401,728✔
405
    @_effect_free_terminates_locally_meta
676✔
406
    a = Vector{Any}(undef, length(vals))
77,639,964✔
407
    @_safeindex for i = 1:length(vals)
25,025,602✔
408
        a[i] = vals[i]
102,622,140✔
409
    end
97,109,023✔
410
    return a
19,554,405✔
411
end
412
getindex(::Type{Any}) = Vector{Any}()
34,915,260✔
413

414
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
415
    ref = a.ref
11,198,638✔
416
    t = @_gc_preserve_begin ref
11,198,638✔
417
    p = unsafe_convert(Ptr{Cvoid}, ref)
11,198,638✔
418
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
11,198,638✔
419
    @_gc_preserve_end t
11,198,638✔
420
    return a
11,198,638✔
421
end
422

423
to_dim(d::Integer) = d
×
424
to_dim(d::OneTo) = last(d)
191✔
425

426
"""
427
    fill(value, dims::Tuple)
428
    fill(value, dims...)
429

430
Create an array of size `dims` with every location set to `value`.
431

432
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
433
with `1.0` in every location of the array.
434

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

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

448
```jldoctest
449
julia> v = fill([], 3)
450
3-element Vector{Vector{Any}}:
451
 []
452
 []
453
 []
454

455
julia> v[1] === v[2] === v[3]
456
true
457

458
julia> value = v[1]
459
Any[]
460

461
julia> push!(value, 867_5309)
462
1-element Vector{Any}:
463
 8675309
464

465
julia> v
466
3-element Vector{Vector{Any}}:
467
 [8675309]
468
 [8675309]
469
 [8675309]
470
```
471

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

475
```jldoctest
476
julia> v2 = [[] for _ in 1:3]
477
3-element Vector{Vector{Any}}:
478
 []
479
 []
480
 []
481

482
julia> v2[1] === v2[2] === v2[3]
483
false
484

485
julia> push!(v2[1], 8675309)
486
1-element Vector{Any}:
487
 8675309
488

489
julia> v2
490
3-element Vector{Vector{Any}}:
491
 [8675309]
492
 []
493
 []
494
```
495

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

498
# Examples
499
```jldoctest
500
julia> fill(1.0, (2,3))
501
2×3 Matrix{Float64}:
502
 1.0  1.0  1.0
503
 1.0  1.0  1.0
504

505
julia> fill(42)
506
0-dimensional Array{Int64, 0}:
507
42
508

509
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
510
2-element Vector{Vector{Float64}}:
511
 [0.0, 0.0]
512
 [0.0, 0.0]
513

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

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

524
fill(v, dims::DimOrInd...) = fill(v, dims)
2,147,483,647✔
525
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
526
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
2,147,483,647✔
527
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
×
528
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
52✔
529

530
"""
531
    zeros([T=Float64,] dims::Tuple)
532
    zeros([T=Float64,] dims...)
533

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

537
# Examples
538
```jldoctest
539
julia> zeros(1)
540
1-element Vector{Float64}:
541
 0.0
542

543
julia> zeros(Int8, 2, 3)
544
2×3 Matrix{Int8}:
545
 0  0  0
546
 0  0  0
547
```
548
"""
549
function zeros end
550

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

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

558
# Examples
559
```jldoctest
560
julia> ones(1,2)
561
1×2 Matrix{Float64}:
562
 1.0  1.0
563

564
julia> ones(ComplexF64, 2, 3)
565
2×3 Matrix{ComplexF64}:
566
 1.0+0.0im  1.0+0.0im  1.0+0.0im
567
 1.0+0.0im  1.0+0.0im  1.0+0.0im
568
```
569
"""
570
function ones end
571

572
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
573
    @eval begin
574
        $fname(dims::DimOrInd...) = $fname(dims)
20,452,253✔
575
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
2,147,483,647✔
576
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
20,452,364✔
577
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
826✔
578
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
12,120✔
579
            a = Array{T,N}(undef, dims)
151,911,225✔
580
            fill!(a, $felt(T))
2,147,483,647✔
581
            return a
104,696,583✔
582
        end
583
        function $fname(::Type{T}, dims::Tuple{}) where {T}
584
            a = Array{T}(undef)
14✔
585
            fill!(a, $felt(T))
14✔
586
            return a
14✔
587
        end
588
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
×
589
            a = similar(Array{T,N}, dims)
×
590
            fill!(a, $felt(T))
×
591
            return a
×
592
        end
593
    end
594
end
595

596
## Conversions ##
597

598
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
202,742✔
599

600
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
78✔
601

602
## Constructors ##
603

604
if nameof(@__MODULE__) === :Base  # avoid method overwrite
605
# constructors should make copies
606
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
212,345✔
607
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
9,398✔
608
end
609

610
## copying iterators to containers
611

612
"""
613
    collect(element_type, collection)
614

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

618
# Examples
619
```jldoctest
620
julia> collect(Float64, 1:2:5)
621
3-element Vector{Float64}:
622
 1.0
623
 3.0
624
 5.0
625
```
626
"""
627
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
21,262,960✔
628

629
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
39,605✔
630
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
631
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
21,223,348✔
632
    a = Vector{T}()
21,223,355✔
633
    for x in itr
36,525,830✔
634
        push!(a, x)
109,526,673✔
635
    end
203,750,870✔
636
    return a
21,223,355✔
637
end
638

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

642
_similar_shape(itr, ::SizeUnknown) = nothing
×
643
_similar_shape(itr, ::HasLength) = length(itr)::Integer
44,390,343✔
644
_similar_shape(itr, ::HasShape) = axes(itr)
518,928,946✔
645

646
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,214,214✔
647
    similar(c, T, 0)
648
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
12,103,646✔
649
    similar(c, T, len)
650
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
274,088✔
651
    similar(c, T, axs)
652

653
# make a collection appropriate for collecting `itr::Generator`
654
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
143✔
655
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
52,628,338✔
656
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
911,767,721✔
657

658
# used by syntax lowering for simple typed comprehensions
659
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
962,769,745✔
660

661

662
"""
663
    collect(collection)
664

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

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

674
# Examples
675

676
Collect items from a `UnitRange{Int64}` collection:
677

678
```jldoctest
679
julia> collect(1:3)
680
3-element Vector{Int64}:
681
 1
682
 2
683
 3
684
```
685

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

688
```jldoctest
689
julia> collect(x^2 for x in 1:3)
690
3-element Vector{Int64}:
691
 1
692
 4
693
 9
694
```
695
"""
696
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
13,536,773✔
697

698
collect(A::AbstractArray) = _collect_indices(axes(A), A)
129,088✔
699

700
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
178,025✔
701

702
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
12,090,584✔
703
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
704

705
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,214,089✔
706
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,214,143✔
707
    for x in itr
2,426,880✔
708
        push!(a,x)
9,866,363✔
709
    end
16,875,861✔
710
    return a
1,214,142✔
711
end
712

713
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
714
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
130,466✔
715
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
716
function _collect_indices(indsA, A)
27✔
717
    B = Array{eltype(A)}(undef, length.(indsA))
232✔
718
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
118✔
719
end
720

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

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

764
function collect(itr::Generator)
877,692✔
765
    isz = IteratorSize(itr.iter)
392,215✔
766
    et = @default_eltype(itr)
767
    if isa(isz, SizeUnknown)
392,215✔
768
        return grow_to!(Vector{et}(), itr)
82,921✔
769
    else
770
        shp = _similar_shape(itr, isz)
806,022✔
771
        y = iterate(itr)
1,599,623✔
772
        if y === nothing
805,395✔
773
            return _array_for(et, isz, shp)
920✔
774
        end
775
        v1, st = y
390,323✔
776
        dest = _array_for(typeof(v1), isz, shp)
1,597,419✔
777
        # The typeassert gives inference a helping hand on the element type and dimensionality
778
        # (work-around for #28382)
779
        et′ = et <: Type ? Type : et
390,323✔
780
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
390,471✔
781
        collect_to_with_first!(dest, v1, itr, st)::RT
10,794,525✔
782
    end
783
end
784

785
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
71✔
786
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
787

788
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
178,045✔
789
    et = @default_eltype(itr)
109,802✔
790
    shp = _similar_shape(itr, isz)
178,052✔
791
    y = iterate(itr)
353,591✔
792
    if y === nothing
178,050✔
793
        return _similar_for(c, et, itr, isz, shp)
2,486✔
794
    end
795
    v1, st = y
109,753✔
796
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
269,978✔
797
    # The typeassert gives inference a helping hand on the element type and dimensionality
798
    # (work-around for #28382)
799
    et′ = et <: Type ? Type : et
109,731✔
800
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
109,744✔
801
    collect_to_with_first!(dest, v1, itr, st)::RT
175,564✔
802
end
803

804
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
83,769✔
805
    i1 = first(LinearIndices(dest))
500,054✔
806
    dest[i1] = v1
980,085✔
807
    return collect_to!(dest, itr, i1+1, st)
11,721,305✔
808
end
809

810
function collect_to_with_first!(dest, v1, itr, st)
×
811
    push!(dest, v1)
×
812
    return grow_to!(dest, itr, st)
×
813
end
814

815
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
229✔
816
    @inline
354✔
817
    new = similar(dest, promote_typejoin(T, typeof(el)))
796✔
818
    f = first(LinearIndices(dest))
354✔
819
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
793✔
820
    @inbounds new[i] = el
399✔
821
    return new
399✔
822
end
823

824
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
120,715✔
825
    # collect to dest array, checking the type of each result. if a result does not
826
    # match, widen the result type and re-dispatch.
827
    i = offs
500,408✔
828
    while true
89,553,288✔
829
        y = iterate(itr, st)
178,126,459✔
830
        y === nothing && break
89,553,279✔
831
        el, st = y
87,181,062✔
832
        if el isa T
87,192,913✔
833
            @inbounds dest[i] = el
88,572,804✔
834
            i += 1
88,572,804✔
835
        else
836
            new = setindex_widen_up_to(dest, el, i)
399✔
837
            return collect_to!(new, itr, i+1, st)
399✔
838
        end
839
    end
88,572,804✔
840
    return dest
980,076✔
841
end
842

843
function grow_to!(dest, itr)
1,171✔
844
    y = iterate(itr)
1,559✔
845
    y === nothing && return dest
1,248✔
846
    dest2 = empty(dest, typeof(y[1]))
339✔
847
    push!(dest2, y[1])
406✔
848
    grow_to!(dest2, itr, y[2])
319✔
849
end
850

851
function push_widen(dest, el)
7✔
852
    @inline
9✔
853
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
9✔
854
    if new isa AbstractSet
9✔
855
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
856
        union!(new, dest)
×
857
    else
858
        append!(new, dest)
18✔
859
    end
860
    push!(new, el)
9✔
861
    return new
9✔
862
end
863

864
function grow_to!(dest, itr, st)
315✔
865
    T = eltype(dest)
206✔
866
    y = iterate(itr, st)
570✔
867
    while y !== nothing
3,733✔
868
        el, st = y
2,070✔
869
        if el isa T
2,072✔
870
            push!(dest, el)
3,408✔
871
        else
872
            new = push_widen(dest, el)
11✔
873
            return grow_to!(new, itr, st)
9✔
874
        end
875
        y = iterate(itr, st)
5,316✔
876
    end
3,406✔
877
    return dest
318✔
878
end
879

880
## Iteration ##
881

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

884
## Indexing: getindex ##
885

886
"""
887
    getindex(collection, key...)
888

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

892
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
893

894
# Examples
895
```jldoctest
896
julia> A = Dict("a" => 1, "b" => 2)
897
Dict{String, Int64} with 2 entries:
898
  "b" => 2
899
  "a" => 1
900

901
julia> getindex(A, "a")
902
1
903
```
904
"""
905
function getindex end
906

907
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
117,013✔
908
    @inline
165,043,069✔
909
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
174,350,220✔
910
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
174,350,590✔
911
end
912

913
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
914
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
6,730,286✔
915
    @inline
797,255✔
916
    @boundscheck checkbounds(A, I)
55,234,462✔
917
    lI = length(I)
55,234,471✔
918
    X = similar(A, axes(I))
86,892,032✔
919
    if lI > 0
55,234,460✔
920
        copyto!(X, firstindex(X), A, first(I), lI)
63,315,132✔
921
    end
922
    return X
55,234,460✔
923
end
924

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

928
function getindex(A::Array, c::Colon)
4,450✔
929
    lI = length(A)
1,787,979✔
930
    X = similar(A, lI)
3,575,956✔
931
    if lI > 0
1,787,979✔
932
        unsafe_copyto!(X, 1, A, 1, lI)
3,575,954✔
933
    end
934
    return X
1,787,979✔
935
end
936

937
# This is redundant with the abstract fallbacks, but needed for bootstrap
938
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
141✔
939
    return S[ A[i] for i in I ]
13,028,888✔
940
end
941

942
## Indexing: setindex! ##
943

944
"""
945
    setindex!(collection, value, key...)
946

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

950
# Examples
951
```jldoctest
952
julia> a = Dict("a"=>1)
953
Dict{String, Int64} with 1 entry:
954
  "a" => 1
955

956
julia> setindex!(a, 2, "b")
957
Dict{String, Int64} with 2 entries:
958
  "b" => 2
959
  "a" => 1
960
```
961
"""
962
function setindex! end
963

964
function setindex!(A::Array{T}, x, i::Int) where {T}
5,474,773✔
965
    @_noub_if_noinbounds_meta
649,657,899✔
966
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
2,147,483,647✔
967
    memoryrefset!(memoryref(A.ref, i, false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
2,147,483,647✔
968
    return A
2,147,483,647✔
969
end
970
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,472✔
971
    @inline
63,798,941✔
972
    @_noub_if_noinbounds_meta
63,798,941✔
973
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
65,993,967✔
974
    memoryrefset!(memoryref(A.ref, _to_linear_index(A, i1, i2, I...), false), x isa T ? x : convert(T,x)::T, :not_atomic, false)
65,994,811✔
975
    return A
65,993,943✔
976
end
977

978
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
1,415,775✔
979
    memoryrefset!(memoryref(A.ref, i, false), x, :not_atomic, false); return A)
249,747,099✔
980
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
294,699✔
981
    memoryrefset!(memoryref(A.ref, i, false), x, :not_atomic, false); return A)
2,147,483,647✔
982
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
983
    __safe_setindex!(A, convert(T, x)::T, i))
23,379✔
984

985
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
986
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
8✔
987
    @_propagate_inbounds_meta
801,242✔
988
    @boundscheck setindex_shape_check(X, length(I))
7,691,580✔
989
    @boundscheck checkbounds(A, I)
7,691,580✔
990
    require_one_based_indexing(X)
801,242✔
991
    X′ = unalias(A, X)
801,242✔
992
    I′ = unalias(A, I)
801,242✔
993
    count = 1
801,242✔
994
    for i in I′
7,691,675✔
995
        @inbounds A[i] = X′[count]
18,371,391✔
996
        count += 1
18,371,391✔
997
    end
30,228,461✔
998
    return A
7,691,580✔
999
end
1000

1001
# Faster contiguous setindex! with copyto!
1002
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
12✔
1003
    @inline
1,008,284✔
1004
    @boundscheck checkbounds(A, I)
1,008,497✔
1005
    lI = length(I)
1,008,497✔
1006
    @boundscheck setindex_shape_check(X, lI)
1,008,497✔
1007
    if lI > 0
1,008,497✔
1008
        unsafe_copyto!(A, first(I), X, 1, lI)
2,016,624✔
1009
    end
1010
    return A
1,008,497✔
1011
end
1012
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
40✔
1013
    @inline
74✔
1014
    lI = length(A)
74✔
1015
    @boundscheck setindex_shape_check(X, lI)
74✔
1016
    if lI > 0
74✔
1017
        unsafe_copyto!(A, 1, X, 1, lI)
148✔
1018
    end
1019
    return A
74✔
1020
end
1021

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

1038
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
2,000,338,560✔
1039

1040
function _growbeg!(a::Vector, delta::Integer)
38✔
1041
    @_noub_meta
12,893✔
1042
    delta = Int(delta)
12,893✔
1043
    delta == 0 && return # avoid attempting to index off the end
18,728,896✔
1044
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
18,728,848✔
1045
    ref = a.ref
58,453,070✔
1046
    mem = ref.mem
58,453,070✔
1047
    len = length(a)
58,453,070✔
1048
    offset = memoryrefoffset(ref)
58,453,070✔
1049
    newlen = len + delta
58,453,070✔
1050
    setfield!(a, :size, (newlen,))
58,453,070✔
1051
    # if offset is far enough advanced to fit data in existing memory without copying
1052
    if delta <= offset - 1
58,453,070✔
1053
        setfield!(a, :ref, @inbounds GenericMemoryRef(ref, 1 - delta))
39,004,636✔
1054
    else
1055
        @noinline (function()
38,897,100✔
1056
        memlen = length(mem)
19,448,667✔
1057
        if offset + len - 1 > memlen || offset < 1
38,897,334✔
1058
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1059
        end
1060
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1061
        # the +1 is because I didn't want to have an off by 1 error.
1062
        newmemlen = max(overallocation(memlen), len + 2 * delta + 1)
29,791,838✔
1063
        newoffset = div(newmemlen - newlen, 2) + 1
19,448,667✔
1064
        # If there is extra data after the end of the array we can use that space so long as there is enough
1065
        # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1066
        # Specifically, we want to ensure that we will only do this operation once before
1067
        # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1068
        if newoffset + newlen < memlen
19,448,667✔
1069
            newoffset = div(memlen - newlen, 2) + 1
×
1070
            newmem = mem
×
1071
        else
1072
            newmem = array_new_memory(mem, newmemlen)
19,448,667✔
1073
        end
1074
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
38,885,531✔
1075
        if ref !== a.ref
19,448,667✔
1076
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1077
        end
1078
        setfield!(a, :ref, @inbounds GenericMemoryRef(newmem, newoffset))
19,448,667✔
1079
        end)()
1080
    end
1081
    return
58,453,070✔
1082
end
1083

1084
function _growend!(a::Vector, delta::Integer)
28✔
1085
    @_noub_meta
7,025,540✔
1086
    delta = Int(delta)
7,044,551✔
1087
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,051,176,283✔
1088
    ref = a.ref
2,147,483,647✔
1089
    mem = ref.mem
2,147,483,647✔
1090
    memlen = length(mem)
2,147,483,647✔
1091
    len = length(a)
2,147,483,647✔
1092
    newlen = len + delta
2,147,483,647✔
1093
    offset = memoryrefoffset(ref)
2,147,483,647✔
1094
    setfield!(a, :size, (newlen,))
2,147,483,647✔
1095
    newmemlen = offset + newlen - 1
2,147,483,647✔
1096
    if memlen < newmemlen
2,147,483,647✔
1097
        @noinline (function()
1,958,778,571✔
1098
        if offset + len - 1 > memlen || offset < 1
1,958,779,567✔
1099
            throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1100
        end
1101

1102
        if offset - 1 > div(5 * newlen, 4)
979,389,783✔
1103
            # If the offset is far enough that we can copy without resizing
1104
            # while maintaining proportional spacing on both ends of the array
1105
            # note that this branch prevents infinite growth when doing combinations
1106
            # of push! and popfirst! (i.e. when using a Vector as a queue)
1107
            newmem = mem
19,422✔
1108
            newoffset = div(newlen, 8) + 1
19,422✔
1109
        else
1110
            # grow either by our computed overallocation factor
1111
            # or exactly the requested size, whichever is larger
1112
            # TODO we should possibly increase the offset if the current offset is nonzero.
1113
            newmemlen2 = max(overallocation(memlen), newmemlen)
1,034,580,290✔
1114
            newmem = array_new_memory(mem, newmemlen2)
1,958,721,689✔
1115
            newoffset = offset
979,370,361✔
1116
        end
1117
        newref = @inbounds GenericMemoryRef(newmem, newoffset)
979,389,784✔
1118
        unsafe_copyto!(newref, ref, len)
1,068,423,108✔
1119
        if ref !== a.ref
979,389,784✔
1120
            @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1121
        end
1122
        setfield!(a, :ref, newref)
979,389,784✔
1123
        end)()
1124
    end
1125
    return
2,147,483,647✔
1126
end
1127

1128
function _growat!(a::Vector, i::Integer, delta::Integer)
85,285,666✔
1129
    @_terminates_globally_noub_meta
176,148✔
1130
    delta = Int(delta)
176,148✔
1131
    i = Int(i)
176,148✔
1132
    i == 1 && return _growbeg!(a, delta)
85,285,666✔
1133
    len = length(a)
66,954,816✔
1134
    i == len + 1 && return _growend!(a, delta)
66,954,816✔
1135
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
65,867,333✔
1136
    1 < i <= len || throw(BoundsError(a, i))
65,867,333✔
1137
    ref = a.ref
65,867,333✔
1138
    mem = ref.mem
65,867,333✔
1139
    memlen = length(mem)
65,867,333✔
1140
    newlen = len + delta
65,867,333✔
1141
    offset = memoryrefoffset(ref)
65,867,333✔
1142
    setfield!(a, :size, (newlen,))
65,867,333✔
1143
    newmemlen = offset + newlen - 1
65,867,333✔
1144

1145
    # which side would we rather grow into?
1146
    prefer_start = i <= div(len, 2)
65,867,333✔
1147
    # if offset is far enough advanced to fit data in beginning of the memory
1148
    if prefer_start && delta <= offset - 1
65,867,333✔
1149
        newref = @inbounds GenericMemoryRef(mem, offset - delta)
27,180,377✔
1150
        unsafe_copyto!(newref, ref, i)
54,360,754✔
1151
        setfield!(a, :ref, newref)
27,180,377✔
1152
        for j in i:i+delta-1
27,180,377✔
1153
            @inbounds _unsetindex!(a, j)
38,342,684✔
1154
        end
38,335,853✔
1155
    elseif !prefer_start && memlen >= newmemlen
38,686,956✔
1156
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
55,292,520✔
1157
        for j in i:i+delta-1
27,646,260✔
1158
            @inbounds _unsetindex!(a, j)
38,366,323✔
1159
        end
38,357,208✔
1160
    else
1161
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1162
        # the +1 is because I didn't want to have an off by 1 error.
1163
        newmemlen = max(overallocation(memlen), len+2*delta+1)
16,142,433✔
1164
        newoffset = (newmemlen - newlen) ÷ 2 + 1
11,040,696✔
1165
        newmem = array_new_memory(mem, newmemlen)
22,081,392✔
1166
        newref = @inbounds GenericMemoryRef(newmem, newoffset)
11,040,696✔
1167
        unsafe_copyto!(newref, ref, i-1)
22,081,392✔
1168
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
22,081,392✔
1169
        setfield!(a, :ref, newref)
11,040,696✔
1170
    end
1171
end
1172

1173
# efficiently delete part of an array
1174
function _deletebeg!(a::Vector, delta::Integer)
16,798,582✔
1175
    delta = Int(delta)
1,041,491✔
1176
    len = length(a)
61,720,347✔
1177
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
61,720,347✔
1178
    for i in 1:delta
17,923,082✔
1179
        @inbounds _unsetindex!(a, i)
80,681,954✔
1180
    end
22,171,106✔
1181
    newlen = len - delta
61,720,347✔
1182
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
61,720,347✔
1183
        newref = @inbounds GenericMemoryRef(a.ref, delta + 1)
56,215,107✔
1184
        setfield!(a, :ref, newref)
56,215,107✔
1185
    end
1186
    setfield!(a, :size, (newlen,))
61,720,347✔
1187
    return
61,720,347✔
1188
end
1189
function _deleteend!(a::Vector, delta::Integer)
18,160,357✔
1190
    delta = Int(delta)
5,841,500✔
1191
    len = length(a)
1,263,951,511✔
1192
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
1,263,951,511✔
1193
    newlen = len - delta
1,263,951,511✔
1194
    for i in newlen+1:len
1,293,602,979✔
1195
        @inbounds _unsetindex!(a, i)
2,147,483,647✔
1196
    end
2,147,483,647✔
1197
    setfield!(a, :size, (newlen,))
1,263,951,511✔
1198
    return
1,263,951,511✔
1199
end
1200
function _deleteat!(a::Vector, i::Integer, delta::Integer)
5,983,054✔
1201
    i = Int(i)
17,723✔
1202
    len = length(a)
5,983,054✔
1203
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
5,983,054✔
1204
    1 <= i <= len || throw(BoundsError(a, i))
5,983,054✔
1205
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
5,983,054✔
1206
    newa = a
17,711✔
1207
    if 2*i + delta <= len
5,983,054✔
1208
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
72,822✔
1209
        _deletebeg!(a, delta)
68,024✔
1210
    else
1211
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
7,933,790✔
1212
        _deleteend!(a, delta)
5,916,103✔
1213
    end
1214
    return
5,983,054✔
1215
end
1216
## Dequeue functionality ##
1217

1218
"""
1219
    push!(collection, items...) -> collection
1220

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

1224
# Examples
1225
```jldoctest
1226
julia> push!([1, 2, 3], 4, 5, 6)
1227
6-element Vector{Int64}:
1228
 1
1229
 2
1230
 3
1231
 4
1232
 5
1233
 6
1234
```
1235

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

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

1242
See also [`pushfirst!`](@ref).
1243
"""
1244
function push! end
1245

1246
function push!(a::Vector{T}, item) where T
52,895✔
1247
    # convert first so we don't grow the array if the assignment won't work
1248
    itemT = item isa T ? item : convert(T, item)::T
35,048,586✔
1249
    _growend!(a, 1)
2,147,483,647✔
1250
    @_safeindex a[length(a)] = itemT
2,147,483,647✔
1251
    return a
2,147,483,647✔
1252
end
1253

1254
# specialize and optimize the single argument case
1255
function push!(a::Vector{Any}, @nospecialize x)
6,752✔
1256
    _growend!(a, 1)
107,267,195✔
1257
    @_safeindex a[length(a)] = x
107,267,195✔
1258
    return a
107,267,195✔
1259
end
1260
function push!(a::Vector{Any}, @nospecialize x...)
16✔
1261
    @_terminates_locally_meta
16✔
1262
    na = length(a)
174,450✔
1263
    nx = length(x)
16✔
1264
    _growend!(a, nx)
174,450✔
1265
    @_safeindex for i = 1:nx
348,884✔
1266
        a[na+i] = x[i]
469,335✔
1267
    end
523,462✔
1268
    return a
174,450✔
1269
end
1270

1271
"""
1272
    append!(collection, collections...) -> collection.
1273

1274
For an ordered container `collection`, add the elements of each `collections`
1275
to the end of it.
1276

1277
!!! compat "Julia 1.6"
1278
    Specifying multiple collections to be appended requires at least Julia 1.6.
1279

1280
# Examples
1281
```jldoctest
1282
julia> append!([1], [2, 3])
1283
3-element Vector{Int64}:
1284
 1
1285
 2
1286
 3
1287

1288
julia> append!([1, 2, 3], [4, 5], [6])
1289
6-element Vector{Int64}:
1290
 1
1291
 2
1292
 3
1293
 4
1294
 5
1295
 6
1296
```
1297

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

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

1304
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1305
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1306
"""
1307
function append! end
1308

1309
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
1,674✔
1310
    items isa Tuple && (items = map(x -> convert(T, x), items))
28,699✔
1311
    n = length(items)
65,533,436✔
1312
    _growend!(a, n)
65,971,543✔
1313
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
102,913,256✔
1314
    return a
65,971,543✔
1315
end
1316

1317
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
69,670,422✔
1318
push!(a::AbstractVector, iter...) = append!(a, iter)
441,026✔
1319

1320
append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
6✔
1321

1322
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
21,239,542✔
1323
    n = Int(length(iter))::Int
21,447,554✔
1324
    i = lastindex(a)
26✔
1325
    sizehint!(a, length(a) + n; shrink=false)
21,239,544✔
1326
    for item in iter
34,826,836✔
1327
        push!(a, item)
41,756,656✔
1328
    end
41,963,777✔
1329
    a
10✔
1330
end
1331
function _append!(a::AbstractVector, ::IteratorSize, iter)
48,430,877✔
1332
    for item in iter
58,383,208✔
1333
        push!(a, item)
49,939,308✔
1334
    end
49,939,309✔
1335
    a
1✔
1336
end
1337

1338
"""
1339
    prepend!(a::Vector, collections...) -> collection
1340

1341
Insert the elements of each `collections` to the beginning of `a`.
1342

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

1346
!!! compat "Julia 1.6"
1347
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1348

1349
# Examples
1350
```jldoctest
1351
julia> prepend!([3], [1, 2])
1352
3-element Vector{Int64}:
1353
 1
1354
 2
1355
 3
1356

1357
julia> prepend!([6], [1, 2], [3, 4, 5])
1358
6-element Vector{Int64}:
1359
 1
1360
 2
1361
 3
1362
 4
1363
 5
1364
 6
1365
```
1366
"""
1367
function prepend! end
1368

1369
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
58✔
1370
    items isa Tuple && (items = map(x -> convert(T, x), items))
735✔
1371
    n = length(items)
1,810✔
1372
    _growbeg!(a, n)
3,571✔
1373
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1374
    # just the last n elements instead of all of them from the first
1375
    copyto!(a, 1, items, lastindex(items)-n+1, n)
3,570✔
1376
    return a
1,810✔
1377
end
1378

1379
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
363✔
1380
pushfirst!(a::Vector, iter...) = prepend!(a, iter)
4✔
1381

1382
prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
102,742✔
1383

1384
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
362✔
1385
    @_terminates_locally_meta
363✔
1386
    require_one_based_indexing(a)
363✔
1387
    n = Int(length(iter))::Int
363✔
1388
    sizehint!(a, length(a) + n; first=true, shrink=false)
363✔
1389
    n = 0
363✔
1390
    for item in iter
363✔
1391
        n += 1
597✔
1392
        pushfirst!(a, item)
597✔
1393
    end
593✔
1394
    reverse!(a, 1, n)
359✔
1395
    a
359✔
1396
end
1397
function _prepend!(a::Vector, ::IteratorSize, iter)
×
1398
    n = 0
×
1399
    for item in iter
×
1400
        n += 1
×
1401
        pushfirst!(a, item)
×
1402
    end
×
1403
    reverse!(a, 1, n)
×
1404
    a
×
1405
end
1406

1407
"""
1408
    resize!(a::Vector, n::Integer) -> Vector
1409

1410
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1411
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1412
guaranteed to be initialized.
1413

1414
# Examples
1415
```jldoctest
1416
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1417
3-element Vector{Int64}:
1418
 6
1419
 5
1420
 4
1421

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

1424
julia> length(a)
1425
8
1426

1427
julia> a[1:6]
1428
6-element Vector{Int64}:
1429
 6
1430
 5
1431
 4
1432
 3
1433
 2
1434
 1
1435
```
1436
"""
1437
function resize!(a::Vector, nl::Integer)
1,129,277,661✔
1438
    l = length(a)
1,176,657,400✔
1439
    if nl > l
1,176,657,400✔
1440
        _growend!(a, nl-l)
816,770,830✔
1441
    elseif nl != l
359,886,572✔
1442
        if nl < 0
90,350,382✔
1443
            _throw_argerror("new length must be ≥ 0")
1✔
1444
        end
1445
        _deleteend!(a, l-nl)
90,350,381✔
1446
    end
1447
    return a
1,176,657,399✔
1448
end
1449

1450
"""
1451
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1452

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

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

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

1466
See also [`resize!`](@ref).
1467

1468
# Notes on the performance model
1469

1470
For types that support `sizehint!`,
1471

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

1476
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1477
   `Base`.
1478

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

1481
!!! compat "Julia 1.11"
1482
    The `shrink` and `first` arguments were added in Julia 1.11.
1483
"""
1484
function sizehint! end
1485

1486
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
42,681,003✔
1487
    len = length(a)
21,339,730✔
1488
    ref = a.ref
21,339,730✔
1489
    mem = ref.mem
21,339,730✔
1490
    memlen = length(mem)
21,339,730✔
1491
    sz = max(Int(sz), len)
21,339,730✔
1492
    inc = sz - len
21,339,730✔
1493
    if sz <= memlen
21,339,730✔
1494
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1495
        if !shrink || memlen - sz <= div(memlen, 8)
18,528,998✔
1496
            return a
18,349,121✔
1497
        end
1498
        newmem = array_new_memory(mem, sz)
132,750✔
1499
        if first
88,349✔
1500
            newref = GenericMemoryRef(newmem, inc + 1)
×
1501
        else
1502
            newref = GenericMemoryRef(newmem)
88,349✔
1503
        end
1504
        unsafe_copyto!(newref, ref, len)
151,839✔
1505
        setfield!(a, :ref, newref)
88,349✔
1506
    elseif first
2,902,260✔
1507
        _growbeg!(a, inc)
718✔
1508
        newref = getfield(a, :ref)
359✔
1509
        newref = GenericMemoryRef(newref, inc + 1)
359✔
1510
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
359✔
1511
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
359✔
1512
    else # last
1513
        _growend!(a, inc)
2,901,901✔
1514
        setfield!(a, :size, (len,)) # undo the size change from _growend!
2,901,901✔
1515
    end
1516
    a
3,962✔
1517
end
1518

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

1528
"""
1529
    pop!(collection) -> item
1530

1531
Remove an item in `collection` and return it. If `collection` is an
1532
ordered container, the last item is returned; for unordered containers,
1533
an arbitrary element is returned.
1534

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

1537
# Examples
1538
```jldoctest
1539
julia> A=[1, 2, 3]
1540
3-element Vector{Int64}:
1541
 1
1542
 2
1543
 3
1544

1545
julia> pop!(A)
1546
3
1547

1548
julia> A
1549
2-element Vector{Int64}:
1550
 1
1551
 2
1552

1553
julia> S = Set([1, 2])
1554
Set{Int64} with 2 elements:
1555
  2
1556
  1
1557

1558
julia> pop!(S)
1559
2
1560

1561
julia> S
1562
Set{Int64} with 1 element:
1563
  1
1564

1565
julia> pop!(Dict(1=>2))
1566
1 => 2
1567
```
1568
"""
1569
function pop!(a::Vector)
20,537✔
1570
    if isempty(a)
1,101,537,578✔
1571
        _throw_argerror("array must be non-empty")
×
1572
    end
1573
    item = a[end]
1,101,537,578✔
1574
    _deleteend!(a, 1)
1,101,537,578✔
1575
    return item
1,101,537,578✔
1576
end
1577

1578
"""
1579
    popat!(a::Vector, i::Integer, [default])
1580

1581
Remove the item at the given `i` and return it. Subsequent items
1582
are shifted to fill the resulting gap.
1583
When `i` is not a valid index for `a`, return `default`, or throw an error if
1584
`default` is not specified.
1585

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

1588
!!! compat "Julia 1.5"
1589
    This function is available as of Julia 1.5.
1590

1591
# Examples
1592
```jldoctest
1593
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1594
3
1595

1596
julia> a
1597
3-element Vector{Int64}:
1598
 4
1599
 2
1600
 1
1601

1602
julia> popat!(a, 4, missing)
1603
missing
1604

1605
julia> popat!(a, 4)
1606
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1607
[...]
1608
```
1609
"""
1610
function popat!(a::Vector, i::Integer)
1611
    x = a[i]
2✔
1612
    _deleteat!(a, i, 1)
2✔
1613
    x
2✔
1614
end
1615

1616
function popat!(a::Vector, i::Integer, default)
×
1617
    if 1 <= i <= length(a)
×
1618
        x = @inbounds a[i]
×
1619
        _deleteat!(a, i, 1)
×
1620
        x
×
1621
    else
1622
        default
×
1623
    end
1624
end
1625

1626
"""
1627
    pushfirst!(collection, items...) -> collection
1628

1629
Insert one or more `items` at the beginning of `collection`.
1630

1631
This function is called `unshift` in many other programming languages.
1632

1633
# Examples
1634
```jldoctest
1635
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1636
6-element Vector{Int64}:
1637
 5
1638
 6
1639
 1
1640
 2
1641
 3
1642
 4
1643
```
1644
"""
1645
function pushfirst!(a::Vector{T}, item) where T
147✔
1646
    item = item isa T ? item : convert(T, item)::T
2,579✔
1647
    _growbeg!(a, 1)
35,758✔
1648
    @_safeindex a[1] = item
33,965✔
1649
    return a
33,965✔
1650
end
1651

1652
# specialize and optimize the single argument case
1653
function pushfirst!(a::Vector{Any}, @nospecialize x)
13✔
1654
    _growbeg!(a, 1)
40,484,959✔
1655
    @_safeindex a[1] = x
39,691,464✔
1656
    return a
39,691,464✔
1657
end
1658
function pushfirst!(a::Vector{Any}, @nospecialize x...)
1✔
1659
    @_terminates_locally_meta
1✔
1660
    na = length(a)
1✔
1661
    nx = length(x)
1✔
1662
    _growbeg!(a, nx)
1,318✔
1663
    @_safeindex for i = 1:nx
1,317✔
1664
        a[i] = x[i]
1,319✔
1665
    end
1,979✔
1666
    return a
659✔
1667
end
1668

1669
"""
1670
    popfirst!(collection) -> item
1671

1672
Remove the first `item` from `collection`.
1673

1674
This function is called `shift` in many other programming languages.
1675

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

1678
# Examples
1679
```jldoctest
1680
julia> A = [1, 2, 3, 4, 5, 6]
1681
6-element Vector{Int64}:
1682
 1
1683
 2
1684
 3
1685
 4
1686
 5
1687
 6
1688

1689
julia> popfirst!(A)
1690
1
1691

1692
julia> A
1693
5-element Vector{Int64}:
1694
 2
1695
 3
1696
 4
1697
 5
1698
 6
1699
```
1700
"""
1701
function popfirst!(a::Vector)
61✔
1702
    if isempty(a)
61,630,518✔
1703
        _throw_argerror("array must be non-empty")
×
1704
    end
1705
    item = a[1]
61,630,518✔
1706
    _deletebeg!(a, 1)
61,630,518✔
1707
    return item
61,630,518✔
1708
end
1709

1710
"""
1711
    insert!(a::Vector, index::Integer, item)
1712

1713
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1714
the resulting `a`.
1715

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

1718
# Examples
1719
```jldoctest
1720
julia> insert!(Any[1:6;], 3, "here")
1721
7-element Vector{Any}:
1722
 1
1723
 2
1724
  "here"
1725
 3
1726
 4
1727
 5
1728
 6
1729
```
1730
"""
1731
function insert!(a::Array{T,1}, i::Integer, item) where T
30✔
1732
    @_noub_meta
1,222,895✔
1733
    # Throw convert error before changing the shape of the array
1734
    _item = item isa T ? item : convert(T, item)::T
1,222,931✔
1735
    _growat!(a, i, 1)
68,484,572✔
1736
    # :noub, because _growat! already did bound check
1737
    @inbounds a[i] = _item
68,484,572✔
1738
    return a
68,484,572✔
1739
end
1740

1741
"""
1742
    deleteat!(a::Vector, i::Integer)
1743

1744
Remove the item at the given `i` and return the modified `a`. Subsequent items
1745
are shifted to fill the resulting gap.
1746

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

1749
# Examples
1750
```jldoctest
1751
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1752
5-element Vector{Int64}:
1753
 6
1754
 4
1755
 3
1756
 2
1757
 1
1758
```
1759
"""
1760
function deleteat!(a::Vector, i::Integer)
130✔
1761
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,557✔
1762
    _deleteat!(a, i, 1)
5,874,545✔
1763
    return a
16,557✔
1764
end
1765

1766
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
131✔
1767
    if eltype(r) === Bool
4,654✔
1768
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
×
1769
    else
1770
        n = length(a)
4,654✔
1771
        f = first(r)
4,654✔
1772
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
4,654✔
1773
        isempty(r) || _deleteat!(a, f, length(r))
220,296✔
1774
        return a
111,903✔
1775
    end
1776
end
1777

1778
"""
1779
    deleteat!(a::Vector, inds)
1780

1781
Remove the items at the indices given by `inds`, and return the modified `a`.
1782
Subsequent items are shifted to fill the resulting gap.
1783

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

1787
# Examples
1788
```jldoctest
1789
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1790
3-element Vector{Int64}:
1791
 5
1792
 3
1793
 1
1794

1795
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1796
3-element Vector{Int64}:
1797
 5
1798
 3
1799
 1
1800

1801
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1802
ERROR: ArgumentError: indices must be unique and sorted
1803
Stacktrace:
1804
[...]
1805
```
1806
"""
1807
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
×
1808
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
61,599✔
1809

1810
struct Nowhere; end
1811
push!(::Nowhere, _) = nothing
×
1812
_growend!(::Nowhere, _) = nothing
×
1813

1814
function _push_deleted!(dltd, a::Vector, ind)
1815
    @_propagate_inbounds_meta
15✔
1816
    if isassigned(a, ind)
67,671✔
1817
        push!(dltd, a[ind])
67,671✔
1818
    else
1819
        _growend!(dltd, 1)
×
1820
    end
1821
end
1822

1823
function _copy_item!(a::Vector, p, q)
1824
    @_propagate_inbounds_meta
21✔
1825
    if isassigned(a, q)
33,561✔
1826
        a[p] = a[q]
33,561✔
1827
    else
1828
        _unsetindex!(a, p)
×
1829
    end
1830
end
1831

1832
function _deleteat!(a::Vector, inds, dltd=Nowhere())
61,599✔
1833
    n = length(a)
123,198✔
1834
    y = iterate(inds)
61,599✔
1835
    y === nothing && return a
61,599✔
1836
    (p, s) = y
4✔
1837
    checkbounds(a, p)
61,592✔
1838
    @inbounds _push_deleted!(dltd, a, p)
61,592✔
1839
    q = p+1
61,592✔
1840
    while true
67,671✔
1841
        y = iterate(inds, s)
67,671✔
1842
        y === nothing && break
67,671✔
1843
        (i,s) = y
11✔
1844
        if !(q <= i <= n)
6,079✔
1845
            if i < q
×
1846
                _throw_argerror("indices must be unique and sorted")
×
1847
            else
1848
                throw(BoundsError())
×
1849
            end
1850
        end
1851
        while q < i
9,616✔
1852
            @inbounds _copy_item!(a, p, q)
3,537✔
1853
            p += 1; q += 1
3,537✔
1854
        end
3,537✔
1855
        @inbounds _push_deleted!(dltd, a, i)
6,079✔
1856
        q = i+1
6,079✔
1857
    end
6,079✔
1858
    while q <= n
91,616✔
1859
        @inbounds _copy_item!(a, p, q)
30,024✔
1860
        p += 1; q += 1
30,024✔
1861
    end
30,024✔
1862
    _deleteend!(a, n-p+1)
67,671✔
1863
    return a
61,592✔
1864
end
1865

1866
# Simpler and more efficient version for logical indexing
1867
function deleteat!(a::Vector, inds::AbstractVector{Bool})
×
1868
    n = length(a)
×
1869
    length(inds) == n || throw(BoundsError(a, inds))
×
1870
    p = 1
×
1871
    for (q, i) in enumerate(inds)
×
1872
        @inbounds _copy_item!(a, p, q)
×
1873
        p += !i
×
1874
    end
×
1875
    _deleteend!(a, n-p+1)
×
1876
    return a
×
1877
end
1878

1879
const _default_splice = []
1880

1881
"""
1882
    splice!(a::Vector, index::Integer, [replacement]) -> item
1883

1884
Remove the item at the given index, and return the removed item.
1885
Subsequent items are shifted left to fill the resulting gap.
1886
If specified, replacement values from an ordered
1887
collection will be spliced in place of the removed item.
1888

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

1891
# Examples
1892
```jldoctest
1893
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1894
2
1895

1896
julia> A
1897
5-element Vector{Int64}:
1898
 6
1899
 5
1900
 4
1901
 3
1902
 1
1903

1904
julia> splice!(A, 5, -1)
1905
1
1906

1907
julia> A
1908
5-element Vector{Int64}:
1909
  6
1910
  5
1911
  4
1912
  3
1913
 -1
1914

1915
julia> splice!(A, 1, [-1, -2, -3])
1916
6
1917

1918
julia> A
1919
7-element Vector{Int64}:
1920
 -1
1921
 -2
1922
 -3
1923
  5
1924
  4
1925
  3
1926
 -1
1927
```
1928

1929
To insert `replacement` before an index `n` without removing any items, use
1930
`splice!(collection, n:n-1, replacement)`.
1931
"""
1932
function splice!(a::Vector, i::Integer, ins=_default_splice)
17✔
1933
    v = a[i]
34✔
1934
    m = length(ins)
17✔
1935
    if m == 0
17✔
1936
        _deleteat!(a, i, 1)
17✔
1937
    elseif m == 1
×
1938
        a[i] = only(ins)
×
1939
    else
1940
        _growat!(a, i, m-1)
×
1941
        k = 1
×
1942
        for x in ins
×
1943
            a[i+k-1] = x
×
1944
            k += 1
×
1945
        end
×
1946
    end
1947
    return v
17✔
1948
end
1949

1950
"""
1951
    splice!(a::Vector, indices, [replacement]) -> items
1952

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

1959
To insert `replacement` before an index `n` without removing any items, use
1960
`splice!(collection, n:n-1, replacement)`.
1961

1962
$(_DOCS_ALIASING_WARNING)
1963

1964
!!! compat "Julia 1.5"
1965
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1966

1967
!!! compat "Julia 1.8"
1968
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1969

1970
# Examples
1971
```jldoctest
1972
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
1973
Int64[]
1974

1975
julia> A
1976
8-element Vector{Int64}:
1977
 -1
1978
 -2
1979
 -3
1980
  2
1981
  5
1982
  4
1983
  3
1984
 -1
1985
```
1986
"""
1987
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
16,801,090✔
1988
    v = a[r]
16,801,098✔
1989
    m = length(ins)
8✔
1990
    if m == 0
8✔
1991
        deleteat!(a, r)
16✔
1992
        return v
8✔
1993
    end
1994

1995
    n = length(a)
16,801,074✔
1996
    f = first(r)
16,801,074✔
1997
    l = last(r)
16,801,074✔
1998
    d = length(r)
16,801,074✔
1999

2000
    if m < d
16,801,074✔
2001
        delta = d - m
×
2002
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
×
2003
    elseif m > d
16,801,074✔
2004
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
16,801,074✔
2005
    end
2006

2007
    k = 1
×
2008
    for x in ins
16,801,074✔
2009
        a[f+k-1] = x
50,403,222✔
2010
        k += 1
50,403,222✔
2011
    end
67,204,296✔
2012
    return v
16,801,074✔
2013
end
2014

2015
splice!(a::Vector, inds) = (dltds = eltype(a)[]; _deleteat!(a, inds, dltds); dltds)
×
2016

2017
function empty!(a::Vector)
53✔
2018
    _deleteend!(a, length(a))
77,086,995✔
2019
    return a
66,140,929✔
2020
end
2021

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

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

2055
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
3,851✔
2056
    len = length(a)
59,572✔
2057
    if len == length(b)
59,572✔
2058
        aref = a.ref
59,448✔
2059
        bref = b.ref
26,539✔
2060
        ta = @_gc_preserve_begin aref
59,448✔
2061
        tb = @_gc_preserve_begin bref
59,448✔
2062
        T = eltype(Arr)
8,110✔
2063
        pa = unsafe_convert(Ptr{T}, aref)
59,448✔
2064
        pb = unsafe_convert(Ptr{T}, bref)
59,448✔
2065
        c = memcmp(pa, pb, sizeof(T) * len)
59,448✔
2066
        @_gc_preserve_end ta
59,448✔
2067
        @_gc_preserve_end tb
59,448✔
2068
        return c == 0
59,448✔
2069
    else
2070
        return false
124✔
2071
    end
2072
end
2073

2074
"""
2075
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2076

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

2080
# Examples
2081
```jldoctest
2082
julia> A = Vector(1:5)
2083
5-element Vector{Int64}:
2084
 1
2085
 2
2086
 3
2087
 4
2088
 5
2089

2090
julia> reverse(A)
2091
5-element Vector{Int64}:
2092
 5
2093
 4
2094
 3
2095
 2
2096
 1
2097

2098
julia> reverse(A, 1, 4)
2099
5-element Vector{Int64}:
2100
 4
2101
 3
2102
 2
2103
 1
2104
 5
2105

2106
julia> reverse(A, 3, 5)
2107
5-element Vector{Int64}:
2108
 1
2109
 2
2110
 5
2111
 4
2112
 3
2113
```
2114
"""
2115
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
7,280✔
2116
    s, n = Int(start), Int(stop)
403✔
2117
    B = similar(A)
14,550✔
2118
    for i = firstindex(A):s-1
7,281✔
2119
        B[i] = A[i]
1,670✔
2120
    end
3,054✔
2121
    for i = s:n
7,290✔
2122
        B[i] = A[n+s-i]
220,972✔
2123
    end
434,674✔
2124
    for i = n+1:lastindex(A)
14,274✔
2125
        B[i] = A[i]
1,670✔
2126
    end
3,054✔
2127
    return B
7,280✔
2128
end
2129

2130
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2131
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2132
    @eval begin
2133
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
126,791,366✔
2134
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
10,566✔
2135
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2136
        function $_f(A::AbstractVector, dim::Integer)
2137
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
1✔
2138
            return $_f(A, :)
1✔
2139
        end
2140
    end
2141
end
2142

2143
function reverseind(a::AbstractVector, i::Integer)
×
2144
    li = LinearIndices(a)
×
2145
    first(li) + last(li) - i
×
2146
end
2147

2148
# This implementation of `midpoint` is performance-optimized but safe
2149
# only if `lo <= hi`.
2150
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
14,819,779✔
2151
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2152

2153
"""
2154
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2155

2156
In-place version of [`reverse`](@ref).
2157

2158
# Examples
2159
```jldoctest
2160
julia> A = Vector(1:5)
2161
5-element Vector{Int64}:
2162
 1
2163
 2
2164
 3
2165
 4
2166
 5
2167

2168
julia> reverse!(A);
2169

2170
julia> A
2171
5-element Vector{Int64}:
2172
 5
2173
 4
2174
 3
2175
 2
2176
 1
2177
```
2178
"""
2179
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
173,829✔
2180
    s, n = Int(start), Int(stop)
144,122✔
2181
    if n > s # non-empty and non-trivial
173,827✔
2182
        liv = LinearIndices(v)
164,764✔
2183
        if !(first(liv) ≤ s ≤ last(liv))
164,764✔
2184
            throw(BoundsError(v, s))
2✔
2185
        elseif !(first(liv) ≤ n ≤ last(liv))
164,762✔
2186
            throw(BoundsError(v, n))
×
2187
        end
2188
        r = n
136,444✔
2189
        @inbounds for i in s:midpoint(s, n-1)
164,762✔
2190
            v[i], v[r] = v[r], v[i]
2,151,434✔
2191
            r -= 1
2,151,434✔
2192
        end
4,138,106✔
2193
    end
2194
    return v
173,825✔
2195
end
2196

2197
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2198

2199
vcat() = Vector{Any}()
10,035✔
2200
hcat() = Vector{Any}()
1✔
2201

2202
function hcat(V::Vector{T}...) where T
59✔
2203
    height = length(V[1])
564✔
2204
    for j = 2:length(V)
564✔
2205
        if length(V[j]) != height
632✔
2206
            throw(DimensionMismatch("vectors must have same lengths"))
×
2207
        end
2208
    end
730✔
2209
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
564✔
2210
end
2211
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2212

2213
function vcat(arrays::Vector{T}...) where T
31,950✔
2214
    n = 0
17,357✔
2215
    for a in arrays
31,950✔
2216
        n += length(a)
2,064,273✔
2217
    end
2,096,220✔
2218
    arr = Vector{T}(undef, n)
63,878✔
2219
    nd = 1
17,357✔
2220
    for a in arrays
31,950✔
2221
        na = length(a)
2,064,273✔
2222
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,064,273✔
2223
        unsafe_copyto!(arr, nd, a, 1, na)
4,124,931✔
2224
        nd += na
2,064,273✔
2225
    end
2,096,220✔
2226
    return arr
31,950✔
2227
end
2228
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
7✔
2229

2230
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))
×
2231

2232
## find ##
2233

2234
"""
2235
    findnext(A, i)
2236

2237
Find the next index after or including `i` of a `true` element of `A`,
2238
or `nothing` if not found.
2239

2240
Indices are of the same type as those returned by [`keys(A)`](@ref)
2241
and [`pairs(A)`](@ref).
2242

2243
# Examples
2244
```jldoctest
2245
julia> A = [false, false, true, false]
2246
4-element Vector{Bool}:
2247
 0
2248
 0
2249
 1
2250
 0
2251

2252
julia> findnext(A, 1)
2253
3
2254

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

2257
julia> A = [false false; true false]
2258
2×2 Matrix{Bool}:
2259
 0  0
2260
 1  0
2261

2262
julia> findnext(A, CartesianIndex(1, 1))
2263
CartesianIndex(2, 1)
2264
```
2265
"""
2266
findnext(A, start) = findnext(identity, A, start)
530✔
2267

2268
"""
2269
    findfirst(A)
2270

2271
Return the index or key of the first `true` value in `A`.
2272
Return `nothing` if no such value is found.
2273
To search for other kinds of values, pass a predicate as the first argument.
2274

2275
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2276
and [`pairs(A)`](@ref).
2277

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

2280
# Examples
2281
```jldoctest
2282
julia> A = [false, false, true, false]
2283
4-element Vector{Bool}:
2284
 0
2285
 0
2286
 1
2287
 0
2288

2289
julia> findfirst(A)
2290
3
2291

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

2294
julia> A = [false false; true false]
2295
2×2 Matrix{Bool}:
2296
 0  0
2297
 1  0
2298

2299
julia> findfirst(A)
2300
CartesianIndex(2, 1)
2301
```
2302
"""
2303
findfirst(A) = findfirst(identity, A)
×
2304

2305
# Needed for bootstrap, and allows defining only an optimized findnext method
2306
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
392✔
2307

2308
"""
2309
    findnext(predicate::Function, A, i)
2310

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

2316
Indices are of the same type as those returned by [`keys(A)`](@ref)
2317
and [`pairs(A)`](@ref).
2318

2319
# Examples
2320
```jldoctest
2321
julia> A = [1, 4, 2, 2];
2322

2323
julia> findnext(isodd, A, 1)
2324
1
2325

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

2328
julia> A = [1 4; 2 2];
2329

2330
julia> findnext(isodd, A, CartesianIndex(1, 1))
2331
CartesianIndex(1, 1)
2332

2333
julia> findnext(isspace, "a b c", 3)
2334
4
2335
```
2336
"""
2337
function findnext(testf::Function, A, start)
14,043✔
2338
    i = oftype(first(keys(A)), start)
16,579✔
2339
    l = last(keys(A))
69,435,656✔
2340
    i > l && return nothing
69,435,656✔
2341
    while true
156,623,913✔
2342
        testf(A[i]) && return i
156,644,739✔
2343
        i == l && break
150,725,981✔
2344
        # nextind(A, l) can throw/overflow
2345
        i = nextind(A, i)
146,830,384✔
2346
    end
146,830,366✔
2347
    return nothing
3,895,593✔
2348
end
2349

2350
"""
2351
    findfirst(predicate::Function, A)
2352

2353
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2354
Return `nothing` if there is no such element.
2355

2356
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2357
and [`pairs(A)`](@ref).
2358

2359
# Examples
2360
```jldoctest
2361
julia> A = [1, 4, 2, 2]
2362
4-element Vector{Int64}:
2363
 1
2364
 4
2365
 2
2366
 2
2367

2368
julia> findfirst(iseven, A)
2369
2
2370

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

2373
julia> findfirst(isequal(4), A)
2374
2
2375

2376
julia> A = [1 4; 2 2]
2377
2×2 Matrix{Int64}:
2378
 1  4
2379
 2  2
2380

2381
julia> findfirst(iseven, A)
2382
CartesianIndex(2, 1)
2383
```
2384
"""
2385
function findfirst(testf::Function, A)
13✔
2386
    for (i, a) in pairs(A)
18✔
2387
        testf(a) && return i
12✔
2388
    end
10✔
2389
    return nothing
7✔
2390
end
2391

2392
# Needed for bootstrap, and allows defining only an optimized findnext method
2393
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
227,528,959✔
2394
    findnext(testf, A, first(keys(A)))
2395

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

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

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

2410
"""
2411
    findprev(A, i)
2412

2413
Find the previous index before or including `i` of a `true` element of `A`,
2414
or `nothing` if not found.
2415

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

2419
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2420

2421
# Examples
2422
```jldoctest
2423
julia> A = [false, false, true, true]
2424
4-element Vector{Bool}:
2425
 0
2426
 0
2427
 1
2428
 1
2429

2430
julia> findprev(A, 3)
2431
3
2432

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

2435
julia> A = [false false; true true]
2436
2×2 Matrix{Bool}:
2437
 0  0
2438
 1  1
2439

2440
julia> findprev(A, CartesianIndex(2, 1))
2441
CartesianIndex(2, 1)
2442
```
2443
"""
2444
findprev(A, start) = findprev(identity, A, start)
×
2445

2446
"""
2447
    findlast(A)
2448

2449
Return the index or key of the last `true` value in `A`.
2450
Return `nothing` if there is no `true` value in `A`.
2451

2452
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2453
and [`pairs(A)`](@ref).
2454

2455
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2456

2457
# Examples
2458
```jldoctest
2459
julia> A = [true, false, true, false]
2460
4-element Vector{Bool}:
2461
 1
2462
 0
2463
 1
2464
 0
2465

2466
julia> findlast(A)
2467
3
2468

2469
julia> A = falses(2,2);
2470

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

2473
julia> A = [true false; true false]
2474
2×2 Matrix{Bool}:
2475
 1  0
2476
 1  0
2477

2478
julia> findlast(A)
2479
CartesianIndex(2, 1)
2480
```
2481
"""
2482
findlast(A) = findlast(identity, A)
22✔
2483

2484
# Needed for bootstrap, and allows defining only an optimized findprev method
2485
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
246✔
2486

2487
"""
2488
    findprev(predicate::Function, A, i)
2489

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

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

2498
# Examples
2499
```jldoctest
2500
julia> A = [4, 6, 1, 2]
2501
4-element Vector{Int64}:
2502
 4
2503
 6
2504
 1
2505
 2
2506

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

2509
julia> findprev(isodd, A, 3)
2510
3
2511

2512
julia> A = [4 6; 1 2]
2513
2×2 Matrix{Int64}:
2514
 4  6
2515
 1  2
2516

2517
julia> findprev(isodd, A, CartesianIndex(1, 2))
2518
CartesianIndex(2, 1)
2519

2520
julia> findprev(isspace, "a b c", 3)
2521
2
2522
```
2523
"""
2524
function findprev(testf::Function, A, start)
292✔
2525
    f = first(keys(A))
28,562✔
2526
    i = oftype(f, start)
28,569✔
2527
    i < f && return nothing
30,256✔
2528
    while true
39,877✔
2529
        testf(A[i]) && return i
40,178✔
2530
        i == f && break
9,738✔
2531
        # prevind(A, f) can throw/underflow
2532
        i = prevind(A, i)
9,648✔
2533
    end
9,622✔
2534
    return nothing
88✔
2535
end
2536

2537
"""
2538
    findlast(predicate::Function, A)
2539

2540
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2541
Return `nothing` if there is no such element.
2542

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

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

2555
julia> findlast(isodd, A)
2556
3
2557

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

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

2565
julia> findlast(isodd, A)
2566
CartesianIndex(2, 1)
2567
```
2568
"""
2569
function findlast(testf::Function, A)
3✔
2570
    for (i, a) in Iterators.reverse(pairs(A))
3✔
2571
        testf(a) && return i
5✔
2572
    end
5✔
2573
    return nothing
1✔
2574
end
2575

2576
# Needed for bootstrap, and allows defining only an optimized findprev method
2577
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
14,807✔
2578
    findprev(testf, A, last(keys(A)))
2579

2580
"""
2581
    findall(f::Function, A)
2582

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

2586
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2587
and [`pairs(A)`](@ref).
2588

2589
# Examples
2590
```jldoctest
2591
julia> x = [1, 3, 4]
2592
3-element Vector{Int64}:
2593
 1
2594
 3
2595
 4
2596

2597
julia> findall(isodd, x)
2598
2-element Vector{Int64}:
2599
 1
2600
 2
2601

2602
julia> A = [1 2 0; 3 4 0]
2603
2×3 Matrix{Int64}:
2604
 1  2  0
2605
 3  4  0
2606
julia> findall(isodd, A)
2607
2-element Vector{CartesianIndex{2}}:
2608
 CartesianIndex(1, 1)
2609
 CartesianIndex(2, 1)
2610

2611
julia> findall(!iszero, A)
2612
4-element Vector{CartesianIndex{2}}:
2613
 CartesianIndex(1, 1)
2614
 CartesianIndex(2, 1)
2615
 CartesianIndex(1, 2)
2616
 CartesianIndex(2, 2)
2617

2618
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2619
Dict{Symbol, Int64} with 3 entries:
2620
  :A => 10
2621
  :B => -1
2622
  :C => 0
2623

2624
julia> findall(≥(0), d)
2625
2-element Vector{Symbol}:
2626
 :A
2627
 :C
2628

2629
```
2630
"""
2631
function findall(testf::Function, A)
23✔
2632
    gen = (first(p) for p in pairs(A) if testf(last(p)))
56✔
2633
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
56✔
2634
end
2635

2636
# Broadcasting is much faster for small testf, and computing
2637
# integer indices from logical index using findall has a negligible cost
2638
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
236✔
2639

2640
"""
2641
    findall(A)
2642

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

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

2650
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2651

2652
# Examples
2653
```jldoctest
2654
julia> A = [true, false, false, true]
2655
4-element Vector{Bool}:
2656
 1
2657
 0
2658
 0
2659
 1
2660

2661
julia> findall(A)
2662
2-element Vector{Int64}:
2663
 1
2664
 4
2665

2666
julia> A = [true false; false true]
2667
2×2 Matrix{Bool}:
2668
 1  0
2669
 0  1
2670

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

2676
julia> findall(falses(3))
2677
Int64[]
2678
```
2679
"""
2680
function findall(A)
2✔
2681
    collect(first(p) for p in pairs(A) if last(p))
2✔
2682
end
2683

2684
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2685
function findall(A::AbstractArray{Bool})
6✔
2686
    n = count(A)
853✔
2687
    I = Vector{eltype(keys(A))}(undef, n)
1,696✔
2688
    cnt = 1
848✔
2689
    for (i,a) in pairs(A)
1,696✔
2690
        if a
81,817✔
2691
            I[cnt] = i
66,620✔
2692
            cnt += 1
66,620✔
2693
        end
2694
    end
162,786✔
2695
    I
848✔
2696
end
2697

2698
findall(x::Bool) = x ? [1] : Vector{Int}()
×
2699
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
×
2700
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
×
2701

2702
# similar to Matlab's ismember
2703
"""
2704
    indexin(a, b)
2705

2706
Return an array containing the first index in `b` for
2707
each value in `a` that is a member of `b`. The output
2708
array contains `nothing` wherever `a` is not a member of `b`.
2709

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

2712
# Examples
2713
```jldoctest
2714
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2715

2716
julia> b = ['a', 'b', 'c'];
2717

2718
julia> indexin(a, b)
2719
6-element Vector{Union{Nothing, Int64}}:
2720
 1
2721
 2
2722
 3
2723
 2
2724
  nothing
2725
 1
2726

2727
julia> indexin(b, a)
2728
3-element Vector{Union{Nothing, Int64}}:
2729
 1
2730
 2
2731
 3
2732
```
2733
"""
2734
function indexin(a, b::AbstractArray)
×
2735
    inds = keys(b)
×
2736
    bdict = Dict{eltype(b),eltype(inds)}()
×
2737
    for (val, ind) in zip(b, inds)
×
2738
        get!(bdict, val, ind)
×
2739
    end
×
2740
    return Union{eltype(inds), Nothing}[
×
2741
        get(bdict, i, nothing) for i in a
2742
    ]
2743
end
2744

2745
function _findin(a::Union{AbstractArray, Tuple}, b)
364✔
2746
    ind  = Vector{eltype(keys(a))}()
550✔
2747
    bset = Set(b)
364✔
2748
    @inbounds for (i,ai) in pairs(a)
585✔
2749
        ai in bset && push!(ind, i)
90,472✔
2750
    end
180,477✔
2751
    ind
364✔
2752
end
2753

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

2799
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
1✔
2800
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
1✔
2801
        return _sortedfindin(x, pred.x)
×
2802
    else
2803
        return _findin(x, pred.x)
1✔
2804
    end
2805
end
2806
# issorted fails for some element types so the method above has to be restricted
2807
# to element with isless/< defined.
2808
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
370✔
2809
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2810

2811
# Copying subregions
2812
function indcopy(sz::Dims, I::Vector)
×
2813
    n = length(I)
×
2814
    s = sz[n]
×
2815
    for i = n+1:length(sz)
×
2816
        s *= sz[i]
×
2817
    end
×
2818
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
×
2819
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
×
2820
    dst, src
×
2821
end
2822

2823
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
×
2824
    n = length(I)
×
2825
    s = sz[n]
×
2826
    for i = n+1:length(sz)
×
2827
        s *= sz[i]
×
2828
    end
×
2829
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
×
2830
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
×
2831
    dst, src
×
2832
end
2833

2834
## Filter ##
2835

2836
"""
2837
    filter(f, a)
2838

2839
Return a copy of collection `a`, removing elements for which `f` is `false`.
2840
The function `f` is passed one argument.
2841

2842
!!! compat "Julia 1.4"
2843
    Support for `a` as a tuple requires at least Julia 1.4.
2844

2845
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2846

2847
# Examples
2848
```jldoctest
2849
julia> a = 1:10
2850
1:10
2851

2852
julia> filter(isodd, a)
2853
5-element Vector{Int64}:
2854
 1
2855
 3
2856
 5
2857
 7
2858
 9
2859
```
2860
"""
2861
function filter(f, a::Array{T, N}) where {T, N}
4,641✔
2862
    j = 1
2,094✔
2863
    b = Vector{T}(undef, length(a))
9,160✔
2864
    for ai in a
4,641✔
2865
        @inbounds b[j] = ai
2,446,414✔
2866
        j = ifelse(f(ai)::Bool, j+1, j)
2,447,584✔
2867
    end
2,446,414✔
2868
    resize!(b, j-1)
4,641✔
2869
    sizehint!(b, length(b))
4,641✔
2870
    b
2,094✔
2871
end
2872

2873
function filter(f, a::AbstractArray)
455✔
2874
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
455✔
2875

2876
    j = 1
455✔
2877
    idxs = Vector{Int}(undef, length(a))
748✔
2878
    for idx in eachindex(a)
458✔
2879
        @inbounds idxs[j] = idx
103,502✔
2880
        ai = @inbounds a[idx]
103,502✔
2881
        j = ifelse(f(ai)::Bool, j+1, j)
105,035✔
2882
    end
206,710✔
2883
    resize!(idxs, j-1)
454✔
2884
    res = a[idxs]
454✔
2885
    empty!(idxs)
4,171✔
2886
    sizehint!(idxs, 0)
454✔
2887
    return res
454✔
2888
end
2889

2890
"""
2891
    filter!(f, a)
2892

2893
Update collection `a`, removing elements for which `f` is `false`.
2894
The function `f` is passed one argument.
2895

2896
# Examples
2897
```jldoctest
2898
julia> filter!(isodd, Vector(1:10))
2899
5-element Vector{Int64}:
2900
 1
2901
 3
2902
 5
2903
 7
2904
 9
2905
```
2906
"""
2907
function filter!(f, a::AbstractVector)
958,817✔
2908
    j = firstindex(a)
808✔
2909
    for ai in a
98,648,041✔
2910
        @inbounds a[j] = ai
115,464,286✔
2911
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
115,493,480✔
2912
    end
115,464,286✔
2913
    j > lastindex(a) && return a
98,648,041✔
2914
    if a isa Vector
368✔
2915
        resize!(a, j-1)
67,220✔
2916
        sizehint!(a, j-1)
67,220✔
2917
    else
2918
        deleteat!(a, j:lastindex(a))
×
2919
    end
2920
    return a
67,220✔
2921
end
2922

2923
"""
2924
    filter(f)
2925

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

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

2932
# Examples
2933
```jldoctest
2934
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2935
(1, 2, 4, 6)
2936

2937
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2938
3-element Vector{Vector{Int64}}:
2939
 [2]
2940
 [2, 4]
2941
 [4]
2942
```
2943
!!! compat "Julia 1.9"
2944
    This method requires at least Julia 1.9.
2945
"""
2946
function filter(f)
×
2947
    Fix1(filter, f)
×
2948
end
2949

2950
"""
2951
    keepat!(a::Vector, inds)
2952
    keepat!(a::BitVector, inds)
2953

2954
Remove the items at all the indices which are not given by `inds`,
2955
and return the modified `a`.
2956
Items which are kept are shifted to fill the resulting gaps.
2957

2958
$(_DOCS_ALIASING_WARNING)
2959

2960
`inds` must be an iterator of sorted and unique integer indices.
2961
See also [`deleteat!`](@ref).
2962

2963
!!! compat "Julia 1.7"
2964
    This function is available as of Julia 1.7.
2965

2966
# Examples
2967
```jldoctest
2968
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
2969
3-element Vector{Int64}:
2970
 6
2971
 4
2972
 2
2973
```
2974
"""
2975
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
2976

2977
"""
2978
    keepat!(a::Vector, m::AbstractVector{Bool})
2979
    keepat!(a::BitVector, m::AbstractVector{Bool})
2980

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

2985
# Examples
2986
```jldoctest
2987
julia> a = [:a, :b, :c];
2988

2989
julia> keepat!(a, [true, false, true])
2990
2-element Vector{Symbol}:
2991
 :a
2992
 :c
2993

2994
julia> a
2995
2-element Vector{Symbol}:
2996
 :a
2997
 :c
2998
```
2999
"""
3000
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
×
3001

3002
# set-like operators for vectors
3003
# These are moderately efficient, preserve order, and remove dupes.
3004

3005
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
17,485✔
3006
    # P, U force specialization
3007
    if pred(x, state)
32,087✔
3008
        update!(state, x)
7,560✔
3009
        true
3010
    else
3011
        false
3012
    end
3013
end
3014

3015
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
183✔
3016
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
1,028✔
3017

3018
function _grow!(pred!, v::AbstractVector, itrs)
79✔
3019
    filter!(pred!, v) # uniquify v
183✔
3020
    for itr in itrs
183✔
3021
        mapfilter(pred!, push!, itr, v)
374✔
3022
    end
557✔
3023
    return v
183✔
3024
end
3025

3026
union!(v::AbstractVector{T}, itrs...) where {T} =
200✔
3027
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3028

3029
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
×
3030
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3031

3032
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
×
3033
    seen = Set{eltype(v)}()
×
3034
    filter!(_grow_filter!(seen), v)
×
3035
    shrinker!(seen, itrs...)
×
3036
    filter!(in(seen), v)
×
3037
end
3038

3039
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
×
3040
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
×
3041

3042
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
1,028✔
3043

3044
function _shrink(shrinker!::F, itr, itrs) where F
966✔
3045
    T = promote_eltype(itr, itrs...)
839✔
3046
    keep = shrinker!(Set{T}(itr), itrs...)
1,984✔
3047
    vectorfilter(T, _shrink_filter!(keep), itr)
978✔
3048
end
3049

3050
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
434✔
3051
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
544✔
3052

3053
function intersect(v::AbstractVector, r::AbstractRange)
1✔
3054
    T = promote_eltype(v, r)
2✔
3055
    common = Iterators.filter(in(r), v)
50✔
3056
    seen = Set{T}(common)
50✔
3057
    return vectorfilter(T, _shrink_filter!(seen), common)
50✔
3058
end
3059
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
1✔
3060

3061
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3062
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
2,712✔
3063
    if i isa Bool # Not via dispatch to avoid ambiguities
24,571,267✔
3064
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3065
    else
3066
        _getindex(v, i)
476,537,442✔
3067
    end
3068
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