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

JuliaLang / julia / #38059

03 May 2025 12:46AM UTC coverage: 25.84% (+0.02%) from 25.818%
#38059

push

local

web-flow
improve isdefined precision for 0 field types (#58220)

alternate to https://github.com/JuliaLang/julia/pull/58214.

---------

Co-authored-by: Jeff Bezanson <jeff.bezanson@gmail.com>

0 of 1 new or added line in 1 file covered. (0.0%)

545 existing lines in 3 files now uncovered.

12959 of 50151 relevant lines covered (25.84%)

1023269.32 hits per line

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

60.25
/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
1✔
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}()
66,233✔
159
function vect(X::T...) where T
2,236✔
160
    @_terminates_locally_meta
4,453✔
161
    vec = Vector{T}(undef, length(X))
16,813✔
162
    @_safeindex for i = 1:length(X)
4,601✔
163
        vec[i] = X[i]
19,618✔
164
    end
10,137✔
165
    return vec
4,527✔
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...)
3✔
184
    T = promote_typeof(X...)
3✔
185
    return T[X...]
3✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
190
    d < 1 && error("arraysize: dimension out of range")
133✔
191
    sz = getfield(a, :size)
1,314✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
1,314✔
193
end
194
size(a::Array) = getfield(a, :size)
150,724,353✔
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))
1,094,315✔
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)
8✔
215

216
function _unsetindex!(A::Array, i::Int)
5,993,184✔
217
    @inline
6,058,035✔
218
    @boundscheck checkbounds(A, i)
43,648,495✔
219
    @inbounds _unsetindex!(memoryref(A.ref, i))
44,538,678✔
220
    return A
22,901,623✔
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)
8✔
226
function elsize(::Type{Ptr{T}}) where T
×
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})
×
230
    T isa DataType || sizeof(Any) # throws
×
231
    return LLT_ALIGN(Core.sizeof(T), datatype_alignment(T))
×
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
4,122✔
236

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

245
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
6,807,486✔
246
    @inline
6,712,750✔
247
    @_noub_if_noinbounds_meta
6,712,750✔
248
    @boundscheck checkbounds(Bool, a, i) || return false
46,938,009✔
249
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
46,938,017✔
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))
336,153✔
269
    return dest
76,988✔
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)
9,196✔
283
    n == 0 && return dest
130,134✔
284
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
101,870✔
285
    return dest
52,449✔
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)
147✔
295
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
×
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)
2,345,513✔
300

301
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
181,611✔
302
    n == 0 && return dest
1,509,191✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
1,180,827✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
1,180,827✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
1,180,827✔
306
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
1,180,826✔
307
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
1,181,532✔
309
    end
310
    return dest
152,000✔
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)))
×
318

319
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
126✔
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))
317,291✔
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
729,520✔
327
    @inline
5,039,190✔
328
    x = x isa T ? x : convert(T, x)::T
5,040,034✔
329
    return _fill!(dest, x)
231,058,187✔
330
end
331
function _fill!(dest::Array{T}, x::T) where T
729,520✔
332
    for i in eachindex(dest)
9,733,450✔
333
        @inbounds dest[i] = x
246,827,881✔
334
    end
468,467,435✔
335
    return dest
7,336,225✔
336
end
337

338
"""
339
    copy(x)
340

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

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

349
@eval function copy(a::Array)
898,820✔
350
    # `copy` only throws when the size exceeds the max allocation size,
351
    # but since we're copying an existing array, we're guaranteed that this will not happen.
352
    @_nothrow_meta
561,825✔
353
    ref = a.ref
5,244,263✔
354
    newmem = typeof(ref.mem)(undef, length(a))
5,244,263✔
355
    @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a))
8,297,351✔
356
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
5,244,264✔
357
end
358

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

370
## Constructors ##
371

372
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
1,236✔
373
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
×
374
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
75✔
375
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
×
376
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
16,582✔
377
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
1,238,915✔
378
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
×
379

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

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

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

395
julia> getindex(Int8, 1, 2, 3)
396
3-element Vector{Int8}:
397
 1
398
 2
399
 3
400
```
401
"""
402
function getindex(::Type{T}, vals...) where T
16,022,465✔
403
    @inline
16,249,213✔
404
    @_effect_free_terminates_locally_meta
16,249,213✔
405
    a = Vector{T}(undef, length(vals))
25,214,905✔
406
    if vals isa NTuple
16,249,213✔
407
        @_safeindex for i in 1:length(vals)
16,248,854✔
408
            a[i] = vals[i]
1,033,512✔
409
        end
169,219✔
410
    else
411
        # use afoldl to avoid type instability inside loop
412
        afoldl(1, vals...) do i, v
363✔
413
            @inbounds a[i] = v
1,096✔
414
            return i + 1
1,096✔
415
        end
416
    end
417
    return a
16,249,266✔
418
end
419

420
function getindex(::Type{Any}, @nospecialize vals...)
867,260✔
421
    @_effect_free_terminates_locally_meta
79,238✔
422
    a = Vector{Any}(undef, length(vals))
922,260✔
423
    @_safeindex for i = 1:length(vals)
518,951✔
424
        a[i] = vals[i]
1,698,987✔
425
    end
1,952,651✔
426
    return a
871,519✔
427
end
428
getindex(::Type{Any}) = Vector{Any}()
773,425✔
429

430
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
431
    ref = a.ref
67,209✔
432
    t = @_gc_preserve_begin ref
67,209✔
433
    p = unsafe_convert(Ptr{Cvoid}, ref)
67,209✔
434
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
67,209✔
435
    @_gc_preserve_end t
67,209✔
436
    return a
61✔
437
end
438

439
to_dim(d::Integer) = d
×
440
to_dim(d::OneTo) = last(d)
×
441

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

540
fill(v, dims::DimOrInd...) = fill(v, dims)
171,006,499✔
541
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
542
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
171,006,490✔
543
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
×
544
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
×
545

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

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

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

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

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

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

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

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

588
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
589
    @eval begin
590
        $fname(dims::DimOrInd...) = $fname(dims)
×
591
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
22,572,321✔
592
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
×
593
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
×
594
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
106,592✔
595
            a = Array{T,N}(undef, dims)
1,400,030✔
596
            fill!(a, $felt(T))
22,572,327✔
597
            return a
1,332,882✔
598
        end
599
        function $fname(::Type{T}, dims::Tuple{}) where {T}
×
600
            a = Array{T}(undef)
×
601
            fill!(a, $felt(T))
×
602
            return a
×
603
        end
604
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
×
605
            a = similar(Array{T,N}, dims)
×
606
            fill!(a, $felt(T))
×
607
            return a
×
608
        end
609
    end
610
end
611

612
## Conversions ##
613

614
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
126✔
615

616
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
×
617

618
## Constructors ##
619

620
# constructors should make copies
621
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
126✔
622
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
×
623

624
## copying iterators to containers
625

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

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

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

643
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
×
644
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
645
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
396,624✔
646
    a = Vector{T}()
396,624✔
647
    for x in itr
396,642✔
648
        push!(a, x)
2,115,980✔
649
    end
2,115,996✔
650
    return a
396,624✔
651
end
652

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

656
_similar_shape(itr, ::SizeUnknown) = nothing
×
657
_similar_shape(itr, ::HasLength) = length(itr)::Integer
449,851✔
658
_similar_shape(itr, ::HasShape) = axes(itr)
5,681,959✔
659

660
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
2,035✔
661
    similar(c, T, 0)
662
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
55,176✔
663
    similar(c, T, len)
664
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
224✔
665
    similar(c, T, axs)
666

667
# make a collection appropriate for collecting `itr::Generator`
668
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
×
669
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
355,479✔
670
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
10,461,185✔
671

672
# used by syntax lowering for simple typed comprehensions
673
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
10,845,328✔
674

675

676
"""
677
    collect(iterator)
678

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

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

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

691
# Examples
692

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

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

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

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

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

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

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

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

730
collect(A::AbstractArray) = _collect_indices(axes(A), A)
×
731

732
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
238✔
733

734
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
65,035✔
735
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
736

737
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
2,035✔
738
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
2,035✔
739
    for x in itr
4,062✔
740
        push!(a,x)
21,033✔
741
    end
39,946✔
742
    return a
2,035✔
743
end
744

745
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
×
746
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
×
747
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
748
function _collect_indices(indsA, A)
×
749
    B = Array{eltype(A)}(undef, length.(indsA))
×
750
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
×
751
end
752

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

767
# define this as a macro so that the call to Core.Compiler
768
# gets inlined into the caller before recursion detection
769
# gets a chance to see it, so that recursive calls to the caller
770
# don't trigger the inference limiter
771
macro default_eltype(itr)
772
    I = esc(itr)
773
    return quote
774
        if $I isa Generator && ($I).f isa Type
2,121✔
775
            T = ($I).f
88✔
776
        else
777
            T = Base._return_type(_iterator_upper_bound, Tuple{typeof($I)})
2,033✔
778
        end
779
        promote_typejoin_union(T)
2,121✔
780
    end
781
end
782

783
function collect(itr::Generator)
1,145✔
784
    isz = IteratorSize(itr.iter)
1,342✔
785
    et = @default_eltype(itr)
786
    if isa(isz, SizeUnknown)
1,342✔
787
        return grow_to!(Vector{et}(), itr)
628✔
788
    else
789
        shp = _similar_shape(itr, isz)
714✔
790
        y = iterate(itr)
1,424✔
791
        if y === nothing
714✔
792
            return _array_for(et, isz, shp)
4✔
793
        end
794
        v1, st = y
710✔
795
        dest = _array_for(typeof(v1), isz, shp)
710✔
796
        # The typeassert gives inference a helping hand on the element type and dimensionality
797
        # (work-around for #28382)
798
        et′ = et <: Type ? Type : et
710✔
799
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
710✔
800
        collect_to_with_first!(dest, v1, itr, st)::RT
710✔
801
    end
802
end
803

804
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
×
805
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
×
806

807
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
209✔
808
    et = @default_eltype(itr)
220✔
809
    shp = _similar_shape(itr, isz)
224✔
810
    y = iterate(itr)
440✔
811
    if y === nothing
224✔
812
        return _similar_for(c, et, itr, isz, shp)
5✔
813
    end
814
    v1, st = y
215✔
815
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
219✔
816
    # The typeassert gives inference a helping hand on the element type and dimensionality
817
    # (work-around for #28382)
818
    et′ = et <: Type ? Type : et
215✔
819
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
215✔
820
    collect_to_with_first!(dest, v1, itr, st)::RT
219✔
821
end
822

823
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
45✔
824
    i1 = first(LinearIndices(dest))
877✔
825
    dest[i1] = v1
930✔
826
    return collect_to!(dest, itr, i1+1, st)
3,330✔
827
end
828

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

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

843
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
441✔
844
    # collect to dest array, checking the type of each result. if a result does not
845
    # match, widen the result type and re-dispatch.
846
    i = offs
914✔
847
    while true
10,652✔
848
        y = iterate(itr, st)
19,970✔
849
        y === nothing && break
10,652✔
850
        el, st = y
7,322✔
851
        if el isa T
7,322✔
852
            @inbounds dest[i] = el
9,722✔
853
            i += 1
9,722✔
854
        else
855
            new = setindex_widen_up_to(dest, el, i)
×
856
            return collect_to!(new, itr, i+1, st)
×
857
        end
858
    end
9,722✔
859
    return dest
930✔
860
end
861

862
function grow_to!(dest, itr)
2✔
863
    y = iterate(itr)
628✔
864
    y === nothing && return dest
628✔
865
    dest2 = empty(dest, typeof(y[1]))
×
866
    push!(dest2, y[1])
×
867
    grow_to!(dest2, itr, y[2])
×
868
end
869

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

883
function grow_to!(dest, itr, st)
×
884
    T = eltype(dest)
×
885
    y = iterate(itr, st)
×
886
    while y !== nothing
×
887
        el, st = y
×
888
        if el isa T
×
889
            push!(dest, el)
×
890
        else
891
            new = push_widen(dest, el)
×
892
            return grow_to!(new, itr, st)
×
893
        end
894
        y = iterate(itr, st)
×
895
    end
×
896
    return dest
×
897
end
898

899
## Iteration ##
900

901
iterate(A::Array, i=1) = (@inline; (i - 1)%UInt < length(A)%UInt ? (@inbounds A[i], i + 1) : nothing)
368,315,814✔
902

903
## Indexing: getindex ##
904

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

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

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

913
# Examples
914
```jldoctest; filter = r"^\\s+\\S+\\s+=>\\s+\\d\$"m
915
julia> A = Dict("a" => 1, "b" => 2)
916
Dict{String, Int64} with 2 entries:
917
  "b" => 2
918
  "a" => 1
919

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

926
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
×
927
    @inline
×
928
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
×
929
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
×
930
end
931

932
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
933
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
157,129✔
934
    @inline
157,200✔
935
    @boundscheck checkbounds(A, I)
1,238,393✔
936
    lI = length(I)
1,238,393✔
937
    X = similar(A, axes(I))
1,238,393✔
938
    if lI > 0
1,238,392✔
939
        copyto!(X, firstindex(X), A, first(I), lI)
1,130,119✔
940
    end
941
    return X
1,229,379✔
942
end
943

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

947
function getindex(A::Array, c::Colon)
398✔
948
    lI = length(A)
16,582✔
949
    X = similar(A, lI)
16,582✔
950
    if lI > 0
16,582✔
951
        unsafe_copyto!(X, 1, A, 1, lI)
32,766✔
952
    end
953
    return X
16,582✔
954
end
955

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

961
## Indexing: setindex! ##
962

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

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

969
# Examples
970
```jldoctest; filter = r"^\\s+\\S+\\s+=>\\s+\\d\$"m
971
julia> a = Dict("a"=>1)
972
Dict{String, Int64} with 1 entry:
973
  "a" => 1
974

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

983
function setindex!(A::Array{T}, x, i::Int) where {T}
109,777,188✔
984
    @_propagate_inbounds_meta
110,090,588✔
985
    x = x isa T ? x : convert(T, x)::T
116,843,827✔
986
    return _setindex!(A, x, i)
775,122,148✔
987
end
988
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
109,774,946✔
989
    @_noub_if_noinbounds_meta
110,088,715✔
990
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
775,120,670✔
991
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
775,122,761✔
992
    return A
524,775,996✔
993
end
994
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
×
995
    @_propagate_inbounds_meta
×
996
    x = x isa T ? x : convert(T, x)::T
×
997
    return _setindex!(A, x, i1, i2, I...)
×
998
end
999
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
×
1000
    @inline
×
1001
    @_noub_if_noinbounds_meta
×
1002
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
×
1003
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
×
1004
    return A
×
1005
end
1006

1007
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
543,275✔
1008
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
5,121,118✔
1009
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
19,640,099✔
1010
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
41,634,231✔
1011
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
×
1012
    __safe_setindex!(A, convert(T, x)::T, i))
×
1013

1014
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1015
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
120,067✔
1016
    @_propagate_inbounds_meta
120,068✔
1017
    @boundscheck setindex_shape_check(X, length(I))
120,068✔
1018
    @boundscheck checkbounds(A, I)
120,068✔
1019
    require_one_based_indexing(X)
120,068✔
1020
    X′ = unalias(A, X)
120,068✔
1021
    I′ = unalias(A, I)
120,068✔
1022
    count = 1
120,068✔
1023
    for i in I′
200,332✔
1024
        @inbounds A[i] = X′[count]
302,588✔
1025
        count += 1
302,588✔
1026
    end
451,538✔
1027
    return A
120,068✔
1028
end
1029

1030
# Faster contiguous setindex! with copyto!
1031
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
1032
    @inline
83✔
1033
    @boundscheck checkbounds(A, I)
84✔
1034
    lI = length(I)
84✔
1035
    @boundscheck setindex_shape_check(X, lI)
84✔
1036
    if lI > 0
84✔
1037
        unsafe_copyto!(A, first(I), X, 1, lI)
44✔
1038
    end
1039
    return A
84✔
1040
end
1041
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
×
1042
    @inline
×
1043
    lI = length(A)
×
1044
    @boundscheck setindex_shape_check(X, lI)
×
1045
    if lI > 0
×
1046
        unsafe_copyto!(A, 1, X, 1, lI)
×
1047
    end
1048
    return A
×
1049
end
1050

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

1067
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
14,173,142✔
1068

1069
function _growbeg_internal!(a::Vector, delta::Int, len::Int)
279,028✔
1070
    @_terminates_locally_meta
279,028✔
1071
    ref = a.ref
279,028✔
1072
    mem = ref.mem
279,028✔
1073
    offset = memoryrefoffset(ref)
279,028✔
1074
    newlen = len + delta
279,028✔
1075
    memlen = length(mem)
279,028✔
1076
    if offset + len - 1 > memlen || offset < 1
558,056✔
UNCOV
1077
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1078
    end
1079
    # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1080
    # the +1 is because I didn't want to have an off by 1 error.
1081
    newmemlen = max(overallocation(len), len + 2 * delta + 1)
424,390✔
1082
    newoffset = div(newmemlen - newlen, 2) + 1
279,028✔
1083
    # If there is extra data after the end of the array we can use that space so long as there is enough
1084
    # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1085
    # Specifically, we want to ensure that we will only do this operation once before
1086
    # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1087
    if newoffset + newlen < memlen
279,028✔
1088
        newoffset = div(memlen - newlen, 2) + 1
306✔
1089
        newmem = mem
306✔
1090
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
602✔
1091
        for j in offset:newoffset+delta-1
306✔
1092
            @inbounds _unsetindex!(mem, j)
2,145✔
1093
        end
3,912✔
1094
    else
1095
        newmem = array_new_memory(mem, newmemlen)
278,722✔
1096
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
278,722✔
1097
    end
1098
    if ref !== a.ref
279,028✔
UNCOV
1099
        throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1100
    end
1101
    setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
279,028✔
1102
end
1103

1104
function _growbeg!(a::Vector, delta::Integer)
118,612✔
1105
    @_noub_meta
118,613✔
1106
    delta = Int(delta)
118,613✔
1107
    delta == 0 && return # avoid attempting to index off the end
335,375✔
1108
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
335,372✔
1109
    ref = a.ref
1,103,325✔
1110
    mem = ref.mem
118,613✔
1111
    len = length(a)
1,103,325✔
1112
    offset = memoryrefoffset(ref)
1,103,325✔
1113
    newlen = len + delta
1,103,325✔
1114
    setfield!(a, :size, (newlen,))
1,103,325✔
1115
    # if offset is far enough advanced to fit data in existing memory without copying
1116
    if delta <= offset - 1
1,103,325✔
1117
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
824,297✔
1118
    else
1119
        @noinline _growbeg_internal!(a, delta, len)
279,028✔
1120
    end
1121
    return
1,100,742✔
1122
end
1123

1124
function _growend_internal!(a::Vector, delta::Int, len::Int)
13,836,342✔
1125
    ref = a.ref
13,836,343✔
1126
    mem = ref.mem
13,836,345✔
1127
    memlen = length(mem)
13,836,347✔
1128
    newlen = len + delta
13,836,347✔
1129
    offset = memoryrefoffset(ref)
13,836,344✔
1130
    newmemlen = offset + newlen - 1
13,836,347✔
1131
    if offset + len - 1 > memlen || offset < 1
27,672,677✔
UNCOV
1132
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1133
    end
1134

1135
    if offset - 1 > div(5 * newlen, 4)
13,836,343✔
1136
        # If the offset is far enough that we can copy without resizing
1137
        # while maintaining proportional spacing on both ends of the array
1138
        # note that this branch prevents infinite growth when doing combinations
1139
        # of push! and popfirst! (i.e. when using a Vector as a queue)
1140
        newmem = mem
922✔
1141
        newoffset = div(newlen, 8) + 1
922✔
1142
    else
1143
        # grow either by our computed overallocation factor
1144
        # or exactly the requested size, whichever is larger
1145
        # TODO we should possibly increase the offset if the current offset is nonzero.
1146
        newmemlen2 = max(overallocation(memlen), newmemlen)
14,613,562✔
1147
        newmem = array_new_memory(mem, newmemlen2)
13,835,549✔
1148
        newoffset = offset
13,835,420✔
1149
    end
1150
    newref = @inbounds memoryref(newmem, newoffset)
13,836,343✔
1151
    unsafe_copyto!(newref, ref, len)
15,127,421✔
1152
    if ref !== a.ref
13,836,347✔
UNCOV
1153
        @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1154
    end
1155
    setfield!(a, :ref, newref)
13,836,345✔
1156
return
13,836,344✔
1157
end
1158

1159
function _growend!(a::Vector, delta::Integer)
13,874,642✔
1160
    @_noub_meta
15,120,893✔
1161
    delta = Int(delta)
15,120,893✔
1162
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
28,988,767✔
1163
    ref = a.ref
52,319,000✔
1164
    mem = ref.mem
52,318,999✔
1165
    memlen = length(mem)
52,319,002✔
1166
    len = length(a)
52,318,992✔
1167
    newlen = len + delta
52,318,999✔
1168
    offset = memoryrefoffset(ref)
52,318,982✔
1169
    setfield!(a, :size, (newlen,))
52,318,979✔
1170
    newmemlen = offset + newlen - 1
52,318,978✔
1171
    if memlen < newmemlen
52,318,981✔
1172
        @noinline _growend_internal!(a, delta, len)
13,840,506✔
1173
    end
1174
    return
49,743,976✔
1175
end
1176

1177
function _growat!(a::Vector, i::Integer, delta::Integer)
1,652,565✔
1178
    @_terminates_globally_noub_meta
1,652,565✔
1179
    delta = Int(delta)
1,652,565✔
1180
    i = Int(i)
1,652,565✔
1181
    i == 1 && return _growbeg!(a, delta)
1,652,565✔
1182
    len = length(a)
1,419,347✔
1183
    i == len + 1 && return _growend!(a, delta)
1,419,348✔
1184
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
1,419,340✔
1185
    1 < i <= len || throw(BoundsError(a, i))
1,419,340✔
1186
    ref = a.ref
1,419,340✔
1187
    mem = ref.mem
1,419,340✔
1188
    memlen = length(mem)
1,419,340✔
1189
    newlen = len + delta
1,419,340✔
1190
    offset = memoryrefoffset(ref)
1,419,340✔
1191
    setfield!(a, :size, (newlen,))
1,419,340✔
1192
    newmemlen = offset + newlen - 1
1,419,340✔
1193

1194
    # which side would we rather grow into?
1195
    prefer_start = i <= div(len, 2)
1,419,340✔
1196
    # if offset is far enough advanced to fit data in beginning of the memory
1197
    if prefer_start && delta <= offset - 1
1,419,340✔
1198
        newref = @inbounds memoryref(mem, offset - delta)
624,289✔
1199
        unsafe_copyto!(newref, ref, i)
1,073,264✔
1200
        setfield!(a, :ref, newref)
624,289✔
1201
        for j in i:i+delta-1
624,289✔
1202
            @inbounds _unsetindex!(a, j)
875,529✔
1203
        end
875,529✔
1204
    elseif !prefer_start && memlen >= newmemlen
795,051✔
1205
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
1,263,490✔
1206
        for j in i:i+delta-1
736,314✔
1207
            @inbounds _unsetindex!(a, j)
1,029,436✔
1208
        end
1,029,436✔
1209
    else
1210
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1211
        # the +1 is because I didn't want to have an off by 1 error.
1212
        newmemlen = max(overallocation(memlen), len+2*delta+1)
79,382✔
1213
        newoffset = (newmemlen - newlen) ÷ 2 + 1
58,737✔
1214
        newmem = array_new_memory(mem, newmemlen)
58,737✔
1215
        newref = @inbounds memoryref(newmem, newoffset)
58,737✔
1216
        unsafe_copyto!(newref, ref, i-1)
108,194✔
1217
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
108,194✔
1218
        setfield!(a, :ref, newref)
58,737✔
1219
    end
1220
end
1221

1222
# efficiently delete part of an array
1223
function _deletebeg!(a::Vector, delta::Integer)
447,530✔
1224
    delta = Int(delta)
511,402✔
1225
    len = length(a)
1,603,782✔
1226
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
1,603,782✔
1227
    for i in 1:delta
513,560✔
1228
        @inbounds _unsetindex!(a, i)
1,879,458✔
1229
    end
532,744✔
1230
    newlen = len - delta
1,603,782✔
1231
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
1,603,782✔
1232
        newref = @inbounds memoryref(a.ref, delta + 1)
1,292,266✔
1233
        setfield!(a, :ref, newref)
1,292,266✔
1234
    end
1235
    setfield!(a, :size, (newlen,))
1,603,782✔
1236
    return
1,603,782✔
1237
end
1238
function _deleteend!(a::Vector, delta::Integer)
3,778,092✔
1239
    delta = Int(delta)
3,778,323✔
1240
    len = length(a)
25,180,094✔
1241
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
25,180,094✔
1242
    newlen = len - delta
25,180,093✔
1243
    for i in newlen+1:len
25,523,231✔
1244
        @inbounds _unsetindex!(a, i)
40,754,261✔
1245
    end
53,624,168✔
1246
    setfield!(a, :size, (newlen,))
25,180,095✔
1247
    return
25,056,124✔
1248
end
1249
function _deleteat!(a::Vector, i::Integer, delta::Integer)
113,036✔
1250
    i = Int(i)
113,036✔
1251
    len = length(a)
113,036✔
1252
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
113,036✔
1253
    1 <= i <= len || throw(BoundsError(a, i))
113,036✔
1254
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
113,036✔
1255
    newa = a
113,036✔
1256
    if 2*i + delta <= len
113,036✔
1257
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
2,297✔
1258
        _deletebeg!(a, delta)
2,221✔
1259
    else
1260
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
143,710✔
1261
        _deleteend!(a, delta)
110,815✔
1262
    end
1263
    return
113,036✔
1264
end
1265
## Dequeue functionality ##
1266

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

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

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

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

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

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

1295
function push!(a::Vector{T}, item) where T
12,751,775✔
1296
    @inline
19,465,932✔
1297
    # convert first so we don't grow the array if the assignment won't work
1298
    # and also to avoid a dynamic dynamic dispatch in the common case that
1299
    # `item` is poorly-typed and `a` is well-typed
1300
    item = item isa T ? item : convert(T, item)::T
20,224,649✔
1301
    return _push!(a, item)
40,581,082✔
1302
end
1303
function _push!(a::Vector{T}, item::T) where T
12,751,613✔
1304
    _growend!(a, 1)
40,581,081✔
1305
    @_safeindex a[length(a)] = item
40,581,086✔
1306
    return a
40,554,317✔
1307
end
1308

1309
# specialize and optimize the single argument case
1310
function push!(a::Vector{Any}, @nospecialize x)
1,527,397✔
1311
    _growend!(a, 1)
2,570,930✔
1312
    @_safeindex a[length(a)] = x
2,570,929✔
1313
    return a
2,570,929✔
1314
end
1315
function push!(a::Vector{Any}, @nospecialize x...)
862✔
1316
    @_terminates_locally_meta
862✔
1317
    na = length(a)
2,516✔
1318
    nx = length(x)
862✔
1319
    _growend!(a, nx)
2,516✔
1320
    @_safeindex for i = 1:nx
4,170✔
1321
        a[na+i] = x[i]
5,032✔
1322
    end
6,686✔
1323
    return a
2,516✔
1324
end
1325

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

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

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

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

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

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

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

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

1364
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
93,057✔
1365
    items isa Tuple && (items = map(x -> convert(T, x), items))
96,259✔
1366
    n = Int(length(items))::Int
646,668✔
1367
    _growend!(a, n)
646,672✔
1368
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
899,473✔
1369
    return a
646,670✔
1370
end
1371

1372
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
1,856,353✔
1373
push!(a::AbstractVector, iter...) = append!(a, iter)
2,982✔
UNCOV
1374
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
×
1375

1376
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
360,262✔
1377
    n = Int(length(iter))::Int
367,377✔
1378
    i = lastindex(a)
360,262✔
1379
    sizehint!(a, length(a) + n; shrink=false)
360,262✔
1380
    for item in iter
515,061✔
1381
        push!(a, item)
1,387,086✔
1382
    end
1,504,543✔
1383
    a
360,262✔
1384
end
1385
function _append!(a::AbstractVector, ::IteratorSize, iter)
1,496,091✔
1386
    for item in iter
1,679,343✔
1387
        push!(a, item)
1,674,211✔
1388
    end
1,688,878✔
1389
    a
1,496,091✔
1390
end
1391

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

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

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

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

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

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

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

1433
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
×
UNCOV
1434
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
×
1435
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
×
1436

1437
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
×
1438
    @_terminates_locally_meta
×
1439
    require_one_based_indexing(a)
×
1440
    n = Int(length(iter))::Int
×
1441
    sizehint!(a, length(a) + n; first=true, shrink=false)
×
1442
    n = 0
×
UNCOV
1443
    for item in iter
×
UNCOV
1444
        n += 1
×
UNCOV
1445
        pushfirst!(a, item)
×
UNCOV
1446
    end
×
UNCOV
1447
    reverse!(a, 1, n)
×
UNCOV
1448
    a
×
1449
end
UNCOV
1450
function _prepend!(a::Vector, ::IteratorSize, iter)
×
UNCOV
1451
    n = 0
×
UNCOV
1452
    for item in iter
×
UNCOV
1453
        n += 1
×
UNCOV
1454
        pushfirst!(a, item)
×
UNCOV
1455
    end
×
UNCOV
1456
    reverse!(a, 1, n)
×
UNCOV
1457
    a
×
1458
end
1459

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

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

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

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

1477
julia> length(a)
1478
8
1479

1480
julia> a[1:6]
1481
6-element Vector{Int64}:
1482
 6
1483
 5
1484
 4
1485
 3
1486
 2
1487
 1
1488
```
1489
"""
1490
function resize!(a::Vector, nl_::Integer)
9,564,259✔
1491
    nl = Int(nl_)::Int
9,564,301✔
1492
    l = length(a)
10,042,052✔
1493
    if nl > l
10,042,052✔
1494
        _growend!(a, nl-l)
5,761,296✔
1495
    elseif nl != l
4,280,756✔
1496
        if nl < 0
1,126,668✔
UNCOV
1497
            _throw_argerror("new length must be ≥ 0")
×
1498
        end
1499
        _deleteend!(a, l-nl)
1,126,668✔
1500
    end
1501
    return a
10,042,047✔
1502
end
1503

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

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

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

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

1520
See also [`resize!`](@ref).
1521

1522
# Notes on the performance model
1523

1524
For types that support `sizehint!`,
1525

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

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

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

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

1540
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
839,666✔
1541
    len = length(a)
418,713✔
1542
    ref = a.ref
418,713✔
1543
    mem = ref.mem
418,713✔
1544
    memlen = length(mem)
418,713✔
1545
    sz = max(Int(sz), len)
418,713✔
1546
    inc = sz - len
418,713✔
1547
    if sz <= memlen
418,713✔
1548
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1549
        if !shrink || memlen - sz <= div(memlen, 8)
291,646✔
1550
            return a
290,560✔
1551
        end
1552
        newmem = array_new_memory(mem, sz)
667✔
1553
        if first
533✔
UNCOV
1554
            newref = memoryref(newmem, inc + 1)
×
1555
        else
1556
            newref = memoryref(newmem)
533✔
1557
        end
1558
        unsafe_copyto!(newref, ref, len)
787✔
1559
        setfield!(a, :ref, newref)
533✔
1560
    elseif first
127,620✔
1561
        _growbeg!(a, inc)
×
1562
        newref = getfield(a, :ref)
×
1563
        newref = memoryref(newref, inc + 1)
×
1564
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
×
UNCOV
1565
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
×
1566
    else # last
1567
        _growend!(a, inc)
127,620✔
1568
        setfield!(a, :size, (len,)) # undo the size change from _growend!
127,620✔
1569
    end
1570
    a
128,153✔
1571
end
1572

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

1582
"""
1583
    pop!(collection) -> item
1584

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

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

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

1599
julia> pop!(A)
1600
3
1601

1602
julia> A
1603
2-element Vector{Int64}:
1604
 1
1605
 2
1606

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

1612
julia> pop!(S)
1613
2
1614

1615
julia> S
1616
Set{Int64} with 1 element:
1617
  1
1618

1619
julia> pop!(Dict(1=>2))
1620
1 => 2
1621
```
1622
"""
1623
function pop!(a::Vector)
3,589,870✔
1624
    if isempty(a)
23,331,564✔
UNCOV
1625
        _throw_argerror("array must be non-empty")
×
1626
    end
1627
    item = a[end]
23,331,568✔
1628
    _deleteend!(a, 1)
23,331,567✔
1629
    return item
23,207,600✔
1630
end
1631

1632
"""
1633
    popat!(a::Vector, i::Integer, [default])
1634

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

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

1642
!!! compat "Julia 1.5"
1643
    This function is available as of Julia 1.5.
1644

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

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

1656
julia> popat!(a, 4, missing)
1657
missing
1658

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

UNCOV
1671
function popat!(a::Vector, i::Integer, default)
×
UNCOV
1672
    if 1 <= i <= length(a)
×
UNCOV
1673
        x = @inbounds a[i]
×
UNCOV
1674
        _deleteat!(a, i, 1)
×
UNCOV
1675
        x
×
1676
    else
UNCOV
1677
        default
×
1678
    end
1679
end
1680

1681
"""
1682
    pushfirst!(collection, items...) -> collection
1683

1684
Insert one or more `items` at the beginning of `collection`.
1685

1686
This function is called `unshift` in many other programming languages.
1687

1688
# Examples
1689
```jldoctest
1690
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1691
6-element Vector{Int64}:
1692
 5
1693
 6
1694
 1
1695
 2
1696
 3
1697
 4
1698
```
1699
"""
1700
function pushfirst!(a::Vector{T}, item) where T
1701
    @inline
1✔
1702
    item = item isa T ? item : convert(T, item)::T
1✔
1703
    return _pushfirst!(a, item)
11✔
1704
end
1705
function _pushfirst!(a::Vector{T}, item::T) where T
1706
    _growbeg!(a, 1)
11✔
1707
    @_safeindex a[1] = item
10✔
1708
    return a
10✔
1709
end
1710

1711
# specialize and optimize the single argument case
1712
function pushfirst!(a::Vector{Any}, @nospecialize x)
85,422✔
1713
    _growbeg!(a, 1)
876,183✔
1714
    @_safeindex a[1] = x
853,366✔
1715
    return a
853,366✔
1716
end
1717
function pushfirst!(a::Vector{Any}, @nospecialize x...)
UNCOV
1718
    @_terminates_locally_meta
×
UNCOV
1719
    na = length(a)
×
UNCOV
1720
    nx = length(x)
×
UNCOV
1721
    _growbeg!(a, nx)
×
UNCOV
1722
    @_safeindex for i = 1:nx
×
UNCOV
1723
        a[i] = x[i]
×
UNCOV
1724
    end
×
UNCOV
1725
    return a
×
1726
end
1727

1728
"""
1729
    popfirst!(collection) -> item
1730

1731
Remove the first `item` from `collection`.
1732

1733
This function is called `shift` in many other programming languages.
1734

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

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

1748
julia> popfirst!(A)
1749
1
1750

1751
julia> A
1752
5-element Vector{Int64}:
1753
 2
1754
 3
1755
 4
1756
 5
1757
 6
1758
```
1759
"""
1760
function popfirst!(a::Vector)
191,104✔
1761
    if isempty(a)
1,601,464✔
UNCOV
1762
        _throw_argerror("array must be non-empty")
×
1763
    end
1764
    item = a[1]
1,601,464✔
1765
    _deletebeg!(a, 1)
1,601,464✔
1766
    return item
1,601,464✔
1767
end
1768

1769
"""
1770
    insert!(a::Vector, index::Integer, item)
1771

1772
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1773
the resulting `a`.
1774

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

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

1804
"""
1805
    deleteat!(a::Vector, i::Integer)
1806

1807
Remove the item at the given `i` and return the modified `a`. Subsequent items
1808
are shifted to fill the resulting gap.
1809

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

1812
# Examples
1813
```jldoctest
1814
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1815
5-element Vector{Int64}:
1816
 6
1817
 4
1818
 3
1819
 2
1820
 1
1821
```
1822
"""
1823
function deleteat!(a::Vector, i::Integer)
14,650✔
1824
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
14,711✔
1825
    _deleteat!(a, i, 1)
112,592✔
1826
    return a
14,711✔
1827
end
1828

1829
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
1830
    if eltype(r) === Bool
1✔
UNCOV
1831
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
×
1832
    else
1833
        n = length(a)
1✔
1834
        f = first(r)
1✔
1835
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
1✔
1836
        isempty(r) || _deleteat!(a, f, length(r))
875✔
1837
        return a
438✔
1838
    end
1839
end
1840

1841
"""
1842
    deleteat!(a::Vector, inds)
1843

1844
Remove the items at the indices given by `inds`, and return the modified `a`.
1845
Subsequent items are shifted to fill the resulting gap.
1846

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

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

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

1864
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1865
ERROR: ArgumentError: indices must be unique and sorted
1866
Stacktrace:
1867
[...]
1868
```
1869
"""
UNCOV
1870
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
×
1871
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
1,388✔
1872

1873
struct Nowhere; end
1874
push!(::Nowhere, _) = nothing
192✔
UNCOV
1875
_growend!(::Nowhere, _) = nothing
×
1876

1877
function _push_deleted!(dltd, a::Vector, ind)
384✔
1878
    @_propagate_inbounds_meta
384✔
1879
    if isassigned(a, ind)
1,618✔
1880
        push!(dltd, a[ind])
1,618✔
1881
    else
UNCOV
1882
        _growend!(dltd, 1)
×
1883
    end
1884
end
1885

1886
function _copy_item!(a::Vector, p, q)
224✔
1887
    @_propagate_inbounds_meta
224✔
1888
    if isassigned(a, q)
870✔
1889
        a[p] = a[q]
870✔
1890
    else
UNCOV
1891
        _unsetindex!(a, p)
×
1892
    end
1893
end
1894

1895
function _deleteat!(a::Vector, inds, dltd=Nowhere())
1,700✔
1896
    n = length(a)
2,776✔
1897
    y = iterate(inds)
1,388✔
1898
    y === nothing && return a
1,388✔
1899
    (p, s) = y
1,383✔
1900
    checkbounds(a, p)
1,383✔
1901
    @inbounds _push_deleted!(dltd, a, p)
1,383✔
1902
    q = p+1
1,383✔
1903
    while true
1,618✔
1904
        y = iterate(inds, s)
1,618✔
1905
        y === nothing && break
1,618✔
1906
        (i,s) = y
235✔
1907
        if !(q <= i <= n)
235✔
UNCOV
1908
            if i < q
×
UNCOV
1909
                _throw_argerror("indices must be unique and sorted")
×
1910
            else
UNCOV
1911
                throw(BoundsError())
×
1912
            end
1913
        end
1914
        while q < i
395✔
1915
            @inbounds _copy_item!(a, p, q)
160✔
1916
            p += 1; q += 1
160✔
1917
        end
160✔
1918
        @inbounds _push_deleted!(dltd, a, i)
235✔
1919
        q = i+1
235✔
1920
    end
235✔
1921
    while q <= n
2,093✔
1922
        @inbounds _copy_item!(a, p, q)
710✔
1923
        p += 1; q += 1
710✔
1924
    end
710✔
1925
    _deleteend!(a, n-p+1)
1,546✔
1926
    return a
1,383✔
1927
end
1928

1929
# Simpler and more efficient version for logical indexing
UNCOV
1930
function deleteat!(a::Vector, inds::AbstractVector{Bool})
×
UNCOV
1931
    n = length(a)
×
UNCOV
1932
    length(inds) == n || throw(BoundsError(a, inds))
×
UNCOV
1933
    p = 1
×
UNCOV
1934
    for (q, i) in enumerate(inds)
×
UNCOV
1935
        @inbounds _copy_item!(a, p, q)
×
UNCOV
1936
        p += !i
×
UNCOV
1937
    end
×
UNCOV
1938
    _deleteend!(a, n-p+1)
×
UNCOV
1939
    return a
×
1940
end
1941

1942
const _default_splice = []
1943

1944
"""
1945
    splice!(a::Vector, index::Integer, [replacement]) -> item
1946

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

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

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

1959
julia> A
1960
5-element Vector{Int64}:
1961
 6
1962
 5
1963
 4
1964
 3
1965
 1
1966

1967
julia> splice!(A, 5, -1)
1968
1
1969

1970
julia> A
1971
5-element Vector{Int64}:
1972
  6
1973
  5
1974
  4
1975
  3
1976
 -1
1977

1978
julia> splice!(A, 1, [-1, -2, -3])
1979
6
1980

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

1992
To insert `replacement` before an index `n` without removing any items, use
1993
`splice!(collection, n:n-1, replacement)`.
1994
"""
1995
function splice!(a::Vector, i::Integer, ins=_default_splice)
14✔
1996
    v = a[i]
14✔
1997
    m = length(ins)
7✔
1998
    if m == 0
7✔
1999
        _deleteat!(a, i, 1)
7✔
UNCOV
2000
    elseif m == 1
×
UNCOV
2001
        a[i] = only(ins)
×
2002
    else
UNCOV
2003
        _growat!(a, i, m-1)
×
UNCOV
2004
        k = 1
×
UNCOV
2005
        for x in ins
×
UNCOV
2006
            a[i+k-1] = x
×
UNCOV
2007
            k += 1
×
UNCOV
2008
        end
×
2009
    end
2010
    return v
7✔
2011
end
2012

2013
"""
2014
    splice!(a::Vector, indices, [replacement]) -> items
2015

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

2022
To insert `replacement` before an index `n` without removing any items, use
2023
`splice!(collection, n:n-1, replacement)`.
2024

2025
$(_DOCS_ALIASING_WARNING)
2026

2027
!!! compat "Julia 1.5"
2028
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
2029

2030
!!! compat "Julia 1.8"
2031
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
2032

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

2038
julia> A
2039
8-element Vector{Int64}:
2040
 -1
2041
 -2
2042
 -3
2043
  2
2044
  5
2045
  4
2046
  3
2047
 -1
2048
```
2049
"""
2050
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
330,500✔
2051
    v = a[r]
330,500✔
2052
    m = length(ins)
330,500✔
2053
    if m == 0
330,500✔
UNCOV
2054
        deleteat!(a, r)
×
UNCOV
2055
        return v
×
2056
    end
2057

2058
    n = length(a)
330,500✔
2059
    f = first(r)
330,500✔
2060
    l = last(r)
330,500✔
2061
    d = length(r)
330,500✔
2062

2063
    if m < d
330,500✔
UNCOV
2064
        delta = d - m
×
UNCOV
2065
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
×
2066
    elseif m > d
330,500✔
2067
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
330,500✔
2068
    end
2069

2070
    k = 1
330,500✔
2071
    for x in ins
330,500✔
2072
        a[f+k-1] = x
991,500✔
2073
        k += 1
991,500✔
2074
    end
1,236,524✔
2075
    return v
330,500✔
2076
end
2077

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

2080
function empty!(a::Vector)
74,972✔
2081
    _deleteend!(a, length(a))
881,282✔
2082
    return a
672,594✔
2083
end
2084

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

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

2118
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
2119
    len = length(a)
20,385✔
2120
    if len == length(b)
20,385✔
2121
        aref = a.ref
20,385✔
2122
        bref = b.ref
20,385✔
2123
        ta = @_gc_preserve_begin aref
20,385✔
2124
        tb = @_gc_preserve_begin bref
20,385✔
UNCOV
2125
        T = eltype(Arr)
×
2126
        pa = unsafe_convert(Ptr{T}, aref)
20,385✔
2127
        pb = unsafe_convert(Ptr{T}, bref)
20,385✔
2128
        c = memcmp(pa, pb, sizeof(T) * len)
20,385✔
2129
        @_gc_preserve_end ta
20,385✔
2130
        @_gc_preserve_end tb
20,385✔
2131
        return c == 0
20,385✔
2132
    else
UNCOV
2133
        return false
×
2134
    end
2135
end
2136

2137
"""
2138
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2139

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

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

2153
julia> reverse(A)
2154
5-element Vector{Int64}:
2155
 5
2156
 4
2157
 3
2158
 2
2159
 1
2160

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

2169
julia> reverse(A, 3, 5)
2170
5-element Vector{Int64}:
2171
 1
2172
 2
2173
 5
2174
 4
2175
 3
2176
```
2177
"""
2178
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
18✔
2179
    s, n = Int(start), Int(stop)
18✔
2180
    B = similar(A)
18✔
2181
    for i = firstindex(A):s-1
18✔
UNCOV
2182
        B[i] = A[i]
×
2183
    end
×
2184
    for i = s:n
18✔
2185
        B[i] = A[n+s-i]
23✔
2186
    end
28✔
2187
    for i = n+1:lastindex(A)
36✔
UNCOV
2188
        B[i] = A[i]
×
UNCOV
2189
    end
×
2190
    return B
18✔
2191
end
2192

2193
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2194
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2195
    @eval begin
2196
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
1,954,090✔
2197
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
154,407✔
UNCOV
2198
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2199
        function $_f(A::AbstractVector, dim::Integer)
×
UNCOV
2200
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
×
UNCOV
2201
            return $_f(A, :)
×
2202
        end
2203
    end
2204
end
2205

UNCOV
2206
function reverseind(a::AbstractVector, i::Integer)
×
UNCOV
2207
    li = LinearIndices(a)
×
UNCOV
2208
    first(li) + last(li) - i
×
2209
end
2210

2211
# This implementation of `midpoint` is performance-optimized but safe
2212
# only if `lo <= hi`.
2213
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
735,392✔
UNCOV
2214
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2215

2216
"""
2217
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2218

2219
In-place version of [`reverse`](@ref).
2220

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

2231
julia> reverse!(A);
2232

2233
julia> A
2234
5-element Vector{Int64}:
2235
 5
2236
 4
2237
 3
2238
 2
2239
 1
2240
```
2241
"""
2242
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
1,871,904✔
2243
    s, n = Int(start), Int(stop)
3,324,627✔
2244
    if n > s # non-empty and non-trivial
1,739,804✔
2245
        liv = LinearIndices(v)
503,786✔
2246
        if !(first(liv) ≤ s ≤ last(liv))
503,786✔
2247
            throw(BoundsError(v, s))
×
2248
        elseif !(first(liv) ≤ n ≤ last(liv))
503,786✔
UNCOV
2249
            throw(BoundsError(v, n))
×
2250
        end
2251
        r = n
503,786✔
2252
        @inbounds for i in s:midpoint(s, n-1)
503,786✔
2253
            v[i], v[r] = v[r], v[i]
512,048✔
2254
            r -= 1
512,048✔
2255
        end
520,310✔
2256
    end
2257
    return v
1,739,804✔
2258
end
2259

2260
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2261

UNCOV
2262
vcat() = Vector{Any}()
×
UNCOV
2263
hcat() = Vector{Any}()
×
2264

UNCOV
2265
function hcat(V::Vector{T}...) where T
×
UNCOV
2266
    height = length(V[1])
×
UNCOV
2267
    for j = 2:length(V)
×
UNCOV
2268
        if length(V[j]) != height
×
UNCOV
2269
            throw(DimensionMismatch("vectors must have same lengths"))
×
2270
        end
UNCOV
2271
    end
×
UNCOV
2272
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
×
2273
end
UNCOV
2274
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
×
2275

2276
function vcat(arrays::Vector{T}...) where T
169✔
2277
    n = 0
169✔
2278
    for a in arrays
169✔
2279
        n += length(a)
494✔
2280
    end
661✔
2281
    arr = Vector{T}(undef, n)
169✔
2282
    nd = 1
169✔
2283
    for a in arrays
169✔
2284
        na = length(a)
494✔
2285
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
494✔
2286
        unsafe_copyto!(arr, nd, a, 1, na)
738✔
2287
        nd += na
494✔
2288
    end
661✔
2289
    return arr
169✔
2290
end
2291
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
1✔
2292

UNCOV
2293
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))
×
2294

2295
## find ##
2296

2297
"""
2298
    findnext(A, i)
2299

2300
Find the next index after or including `i` of a `true` element of `A`,
2301
or `nothing` if not found.
2302

2303
Indices are of the same type as those returned by [`keys(A)`](@ref)
2304
and [`pairs(A)`](@ref).
2305

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

2315
julia> findnext(A, 1)
2316
3
2317

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

2320
julia> A = [false false; true false]
2321
2×2 Matrix{Bool}:
2322
 0  0
2323
 1  0
2324

2325
julia> findnext(A, CartesianIndex(1, 1))
2326
CartesianIndex(2, 1)
2327
```
2328
"""
UNCOV
2329
findnext(A, start) = findnext(identity, A, start)
×
2330

2331
"""
2332
    findfirst(A)
2333

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

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

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

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

2352
julia> findfirst(A)
2353
3
2354

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

2357
julia> A = [false false; true false]
2358
2×2 Matrix{Bool}:
2359
 0  0
2360
 1  0
2361

2362
julia> findfirst(A)
2363
CartesianIndex(2, 1)
2364
```
2365
"""
UNCOV
2366
findfirst(A) = findfirst(identity, A)
×
2367

2368
# Needed for bootstrap, and allows defining only an optimized findnext method
2369
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
74✔
2370

2371
"""
2372
    findnext(predicate::Function, A, i)
2373

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

2379
Indices are of the same type as those returned by [`keys(A)`](@ref)
2380
and [`pairs(A)`](@ref).
2381

2382
# Examples
2383
```jldoctest
2384
julia> A = [1, 4, 2, 2];
2385

2386
julia> findnext(isodd, A, 1)
2387
1
2388

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

2391
julia> A = [1 4; 2 2];
2392

2393
julia> findnext(isodd, A, CartesianIndex(1, 1))
2394
CartesianIndex(1, 1)
2395

2396
julia> findnext(isspace, "a b c", 3)
2397
4
2398
```
2399
"""
2400
function findnext(testf::Function, A, start)
492,023✔
2401
    i = oftype(first(keys(A)), start)
493,585✔
2402
    l = last(keys(A))
1,911,438✔
2403
    i > l && return nothing
1,911,438✔
2404
    while true
960,045✔
2405
        testf(A[i]) && return i
973,785✔
2406
        i == l && break
851,801✔
2407
        # nextind(A, l) can throw/overflow
2408
        i = nextind(A, i)
578,441✔
2409
    end
578,441✔
2410
    return nothing
273,360✔
2411
end
2412

2413
"""
2414
    findfirst(predicate::Function, A)
2415

2416
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2417
Return `nothing` if there is no such element.
2418

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

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

2431
julia> findfirst(iseven, A)
2432
2
2433

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

2436
julia> findfirst(isequal(4), A)
2437
2
2438

2439
julia> A = [1 4; 2 2]
2440
2×2 Matrix{Int64}:
2441
 1  4
2442
 2  2
2443

2444
julia> findfirst(iseven, A)
2445
CartesianIndex(2, 1)
2446
```
2447
"""
2448
function findfirst(testf::Function, A)
1✔
2449
    for (i, a) in pairs(A)
1✔
2450
        testf(a) && return i
×
2451
    end
×
2452
    return nothing
1✔
2453
end
2454

2455
# Needed for bootstrap, and allows defining only an optimized findnext method
2456
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
3,232,131✔
2457
    findnext(testf, A, first(keys(A)))
2458

2459
findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::OneTo) where {T<:Integer} =
×
2460
    1 <= p.x <= r.stop ? convert(keytype(r), p.x) : nothing
2461

UNCOV
2462
findfirst(::typeof(iszero), ::OneTo) = nothing
×
UNCOV
2463
findfirst(::typeof(isone), r::OneTo) = isempty(r) ? nothing : oneunit(keytype(r))
×
2464

2465
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::AbstractUnitRange{<:Integer}) where {T<:Integer}
×
UNCOV
2466
    first(r) <= p.x <= last(r) || return nothing
×
UNCOV
2467
    i1 = first(keys(r))
×
UNCOV
2468
    return i1 + oftype(i1, p.x - first(r))
×
2469
end
2470

UNCOV
2471
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
×
UNCOV
2472
    isempty(r) && return nothing
×
UNCOV
2473
    minimum(r) <= p.x <= maximum(r) || return nothing
×
UNCOV
2474
    d = p.x - first(r)
×
UNCOV
2475
    iszero(d % step(r)) || return nothing
×
UNCOV
2476
    return convert(keytype(r), d ÷ step(r) + 1)
×
2477
end
2478

UNCOV
2479
findfirst(::typeof(iszero), r::AbstractRange) = findfirst(==(zero(first(r))), r)
×
UNCOV
2480
findfirst(::typeof(isone), r::AbstractRange) = findfirst(==(one(first(r))), r)
×
2481

2482
"""
2483
    findprev(A, i)
2484

2485
Find the previous index before or including `i` of a `true` element of `A`,
2486
or `nothing` if not found.
2487

2488
Indices are of the same type as those returned by [`keys(A)`](@ref)
2489
and [`pairs(A)`](@ref).
2490

2491
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2492

2493
# Examples
2494
```jldoctest
2495
julia> A = [false, false, true, true]
2496
4-element Vector{Bool}:
2497
 0
2498
 0
2499
 1
2500
 1
2501

2502
julia> findprev(A, 3)
2503
3
2504

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

2507
julia> A = [false false; true true]
2508
2×2 Matrix{Bool}:
2509
 0  0
2510
 1  1
2511

2512
julia> findprev(A, CartesianIndex(2, 1))
2513
CartesianIndex(2, 1)
2514
```
2515
"""
UNCOV
2516
findprev(A, start) = findprev(identity, A, start)
×
2517

2518
"""
2519
    findlast(A)
2520

2521
Return the index or key of the last `true` value in `A`.
2522
Return `nothing` if there is no `true` value in `A`.
2523

2524
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2525
and [`pairs(A)`](@ref).
2526

2527
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2528

2529
# Examples
2530
```jldoctest
2531
julia> A = [true, false, true, false]
2532
4-element Vector{Bool}:
2533
 1
2534
 0
2535
 1
2536
 0
2537

2538
julia> findlast(A)
2539
3
2540

2541
julia> A = falses(2,2);
2542

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

2545
julia> A = [true false; true false]
2546
2×2 Matrix{Bool}:
2547
 1  0
2548
 1  0
2549

2550
julia> findlast(A)
2551
CartesianIndex(2, 1)
2552
```
2553
"""
UNCOV
2554
findlast(A) = findlast(identity, A)
×
2555

2556
# Needed for bootstrap, and allows defining only an optimized findprev method
2557
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
241✔
2558

2559
"""
2560
    findprev(predicate::Function, A, i)
2561

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

2567
Indices are of the same type as those returned by [`keys(A)`](@ref)
2568
and [`pairs(A)`](@ref).
2569

2570
# Examples
2571
```jldoctest
2572
julia> A = [4, 6, 1, 2]
2573
4-element Vector{Int64}:
2574
 4
2575
 6
2576
 1
2577
 2
2578

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

2581
julia> findprev(isodd, A, 3)
2582
3
2583

2584
julia> A = [4 6; 1 2]
2585
2×2 Matrix{Int64}:
2586
 4  6
2587
 1  2
2588

2589
julia> findprev(isodd, A, CartesianIndex(1, 2))
2590
CartesianIndex(2, 1)
2591

2592
julia> findprev(isspace, "a b c", 3)
2593
2
2594
```
2595
"""
2596
function findprev(testf::Function, A, start)
96✔
2597
    f = first(keys(A))
157✔
2598
    i = oftype(f, start)
157✔
2599
    i < f && return nothing
157✔
2600
    while true
608✔
2601
        testf(A[i]) && return i
875✔
2602
        i == f && break
455✔
2603
        # prevind(A, f) can throw/underflow
2604
        i = prevind(A, i)
451✔
2605
    end
451✔
2606
    return nothing
4✔
2607
end
2608

2609
"""
2610
    findlast(predicate::Function, A)
2611

2612
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2613
Return `nothing` if there is no such element.
2614

2615
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2616
and [`pairs(A)`](@ref).
2617

2618
# Examples
2619
```jldoctest
2620
julia> A = [1, 2, 3, 4]
2621
4-element Vector{Int64}:
2622
 1
2623
 2
2624
 3
2625
 4
2626

2627
julia> findlast(isodd, A)
2628
3
2629

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

2632
julia> A = [1 2; 3 4]
2633
2×2 Matrix{Int64}:
2634
 1  2
2635
 3  4
2636

2637
julia> findlast(isodd, A)
2638
CartesianIndex(2, 1)
2639
```
2640
"""
UNCOV
2641
function findlast(testf::Function, A)
×
UNCOV
2642
    for (i, a) in Iterators.reverse(pairs(A))
×
2643
        testf(a) && return i
×
UNCOV
2644
    end
×
2645
    return nothing
×
2646
end
2647

2648
# Needed for bootstrap, and allows defining only an optimized findprev method
2649
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
425✔
2650
    findprev(testf, A, last(keys(A)))
2651

2652
# for monotonic ranges, there is a unique index corresponding to a value, so findfirst and findlast are identical
UNCOV
2653
function findlast(p::Union{Fix2{typeof(isequal),<:Integer},Fix2{typeof(==),<:Integer},typeof(iszero),typeof(isone)},
×
2654
        r::AbstractUnitRange{<:Integer})
UNCOV
2655
    findfirst(p, r)
×
2656
end
2657

UNCOV
2658
function findlast(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T},typeof(iszero),typeof(isone)},
×
2659
        r::StepRange{T,S}) where {T,S}
UNCOV
2660
    findfirst(p, r)
×
2661
end
2662

2663
"""
2664
    findall(f::Function, A)
2665

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

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

2672
# Examples
2673
```jldoctest
2674
julia> x = [1, 3, 4]
2675
3-element Vector{Int64}:
2676
 1
2677
 3
2678
 4
2679

2680
julia> findall(isodd, x)
2681
2-element Vector{Int64}:
2682
 1
2683
 2
2684

2685
julia> A = [1 2 0; 3 4 0]
2686
2×3 Matrix{Int64}:
2687
 1  2  0
2688
 3  4  0
2689
julia> findall(isodd, A)
2690
2-element Vector{CartesianIndex{2}}:
2691
 CartesianIndex(1, 1)
2692
 CartesianIndex(2, 1)
2693

2694
julia> findall(!iszero, A)
2695
4-element Vector{CartesianIndex{2}}:
2696
 CartesianIndex(1, 1)
2697
 CartesianIndex(2, 1)
2698
 CartesianIndex(1, 2)
2699
 CartesianIndex(2, 2)
2700

2701
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2702
Dict{Symbol, Int64} with 3 entries:
2703
  :A => 10
2704
  :B => -1
2705
  :C => 0
2706

2707
julia> findall(≥(0), d)
2708
2-element Vector{Symbol}:
2709
 :A
2710
 :C
2711

2712
```
2713
"""
UNCOV
2714
function findall(testf::Function, A)
×
UNCOV
2715
    gen = (first(p) for p in pairs(A) if testf(last(p)))
×
UNCOV
2716
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
×
2717
end
2718

2719
# Broadcasting is much faster for small testf, and computing
2720
# integer indices from logical index using findall has a negligible cost
2721
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
11✔
2722

2723
"""
2724
    findall(A)
2725

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

2730
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2731
and [`pairs(A)`](@ref).
2732

2733
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2734

2735
# Examples
2736
```jldoctest
2737
julia> A = [true, false, false, true]
2738
4-element Vector{Bool}:
2739
 1
2740
 0
2741
 0
2742
 1
2743

2744
julia> findall(A)
2745
2-element Vector{Int64}:
2746
 1
2747
 4
2748

2749
julia> A = [true false; false true]
2750
2×2 Matrix{Bool}:
2751
 1  0
2752
 0  1
2753

2754
julia> findall(A)
2755
2-element Vector{CartesianIndex{2}}:
2756
 CartesianIndex(1, 1)
2757
 CartesianIndex(2, 2)
2758

2759
julia> findall(falses(3))
2760
Int64[]
2761
```
2762
"""
2763
function findall(A)
×
UNCOV
2764
    collect(first(p) for p in pairs(A) if last(p))
×
2765
end
2766

2767
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2768
function findall(A::AbstractArray{Bool})
×
UNCOV
2769
    n = count(A)
×
UNCOV
2770
    I = Vector{eltype(keys(A))}(undef, n)
×
UNCOV
2771
    cnt = 1
×
UNCOV
2772
    for (i,a) in pairs(A)
×
UNCOV
2773
        if a
×
UNCOV
2774
            I[cnt] = i
×
UNCOV
2775
            cnt += 1
×
2776
        end
UNCOV
2777
    end
×
UNCOV
2778
    I
×
2779
end
2780

UNCOV
2781
findall(x::Bool) = x ? [1] : Vector{Int}()
×
UNCOV
2782
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
×
UNCOV
2783
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
×
2784

2785
# similar to Matlab's ismember
2786
"""
2787
    indexin(a, b)
2788

2789
Return an array containing the first index in `b` for
2790
each value in `a` that is a member of `b`. The output
2791
array contains `nothing` wherever `a` is not a member of `b`.
2792

2793
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2794

2795
# Examples
2796
```jldoctest
2797
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2798

2799
julia> b = ['a', 'b', 'c'];
2800

2801
julia> indexin(a, b)
2802
6-element Vector{Union{Nothing, Int64}}:
2803
 1
2804
 2
2805
 3
2806
 2
2807
  nothing
2808
 1
2809

2810
julia> indexin(b, a)
2811
3-element Vector{Union{Nothing, Int64}}:
2812
 1
2813
 2
2814
 3
2815
```
2816
"""
2817
function indexin(a, b::AbstractArray)
×
2818
    inds = keys(b)
×
UNCOV
2819
    bdict = Dict{eltype(b),eltype(inds)}()
×
2820
    for (val, ind) in zip(b, inds)
×
UNCOV
2821
        get!(bdict, val, ind)
×
UNCOV
2822
    end
×
UNCOV
2823
    return Union{eltype(inds), Nothing}[
×
2824
        get(bdict, i, nothing) for i in a
2825
    ]
2826
end
2827

2828
function _findin(a::Union{AbstractArray, Tuple}, b::AbstractSet)
×
2829
    ind  = Vector{eltype(keys(a))}()
×
2830
    @inbounds for (i,ai) in pairs(a)
×
UNCOV
2831
        ai in b && push!(ind, i)
×
2832
    end
×
2833
    ind
×
2834
end
2835
_findin(a::Union{AbstractArray, Tuple}, b) = _findin(a, Set(b))
×
2836

2837
# If two collections are already sorted, _findin can be computed with
2838
# a single traversal of the two collections. This is much faster than
2839
# using a hash table (although it has the same complexity).
2840
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
×
UNCOV
2841
    viter, witer = keys(v), eachindex(w)
×
2842
    out  = eltype(viter)[]
×
2843
    vy, wy = iterate(viter), iterate(witer)
×
2844
    if vy === nothing || wy === nothing
×
2845
        return out
×
2846
    end
2847
    viteri, i = vy
×
UNCOV
2848
    witerj, j = wy
×
2849
    @inbounds begin
×
2850
        vi, wj = v[viteri], w[witerj]
×
UNCOV
2851
        while true
×
2852
            if isless(vi, wj)
×
2853
                vy = iterate(viter, i)
×
2854
                if vy === nothing
×
2855
                    break
×
2856
                end
UNCOV
2857
                viteri, i = vy
×
UNCOV
2858
                vi        = v[viteri]
×
2859
            elseif isless(wj, vi)
×
2860
                wy = iterate(witer, j)
×
UNCOV
2861
                if wy === nothing
×
2862
                    break
×
2863
                end
2864
                witerj, j = wy
×
UNCOV
2865
                wj        = w[witerj]
×
2866
            else
2867
                push!(out, viteri)
×
2868
                vy = iterate(viter, i)
×
2869
                if vy === nothing
×
UNCOV
2870
                    break
×
2871
                end
2872
                # We only increment the v iterator because v can have
2873
                # repeated matches to a single value in w
UNCOV
2874
                viteri, i = vy
×
UNCOV
2875
                vi        = v[viteri]
×
2876
            end
2877
        end
×
2878
    end
UNCOV
2879
    return out
×
2880
end
2881

2882
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
×
2883
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
×
2884
        return _sortedfindin(x, pred.x)
×
2885
    else
2886
        return _findin(x, pred.x)
×
2887
    end
2888
end
2889
# issorted fails for some element types so the method above has to be restricted
2890
# to element with isless/< defined.
2891
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
×
2892
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2893

2894
# Copying subregions
2895
function indcopy(sz::Dims, I::Vector)
×
2896
    n = length(I)
×
2897
    s = sz[n]
×
2898
    for i = n+1:length(sz)
×
2899
        s *= sz[i]
×
UNCOV
2900
    end
×
UNCOV
2901
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
×
UNCOV
2902
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
×
UNCOV
2903
    dst, src
×
2904
end
2905

UNCOV
2906
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
×
UNCOV
2907
    n = length(I)
×
UNCOV
2908
    s = sz[n]
×
UNCOV
2909
    for i = n+1:length(sz)
×
UNCOV
2910
        s *= sz[i]
×
UNCOV
2911
    end
×
UNCOV
2912
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
×
UNCOV
2913
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
×
UNCOV
2914
    dst, src
×
2915
end
2916

2917
## Filter ##
2918

2919
"""
2920
    filter(f, a)
2921

2922
Return a copy of collection `a`, removing elements for which `f` is `false`.
2923
The function `f` is passed one argument.
2924

2925
!!! compat "Julia 1.4"
2926
    Support for `a` as a tuple requires at least Julia 1.4.
2927

2928
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2929

2930
# Examples
2931
```jldoctest
2932
julia> a = 1:10
2933
1:10
2934

2935
julia> filter(isodd, a)
2936
5-element Vector{Int64}:
2937
 1
2938
 3
2939
 5
2940
 7
2941
 9
2942
```
2943
"""
2944
function filter(f, a::Array{T, N}) where {T, N}
132✔
2945
    j = 1
132✔
2946
    b = Vector{T}(undef, length(a))
132✔
2947
    for ai in a
132✔
2948
        @inbounds b[j] = ai
767✔
2949
        j = ifelse(f(ai)::Bool, j+1, j)
771✔
2950
    end
767✔
2951
    resize!(b, j-1)
132✔
2952
    sizehint!(b, length(b))
132✔
2953
    b
132✔
2954
end
2955

UNCOV
2956
function filter(f, a::AbstractArray)
×
UNCOV
2957
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
×
2958

UNCOV
2959
    j = 1
×
UNCOV
2960
    idxs = Vector{Int}(undef, length(a))
×
UNCOV
2961
    for idx in eachindex(a)
×
UNCOV
2962
        @inbounds idxs[j] = idx
×
UNCOV
2963
        ai = @inbounds a[idx]
×
UNCOV
2964
        j = ifelse(f(ai)::Bool, j+1, j)
×
UNCOV
2965
    end
×
UNCOV
2966
    resize!(idxs, j-1)
×
UNCOV
2967
    res = a[idxs]
×
UNCOV
2968
    empty!(idxs)
×
UNCOV
2969
    sizehint!(idxs, 0)
×
UNCOV
2970
    return res
×
2971
end
2972

2973
"""
2974
    filter!(f, a)
2975

2976
Update collection `a`, removing elements for which `f` is `false`.
2977
The function `f` is passed one argument.
2978

2979
# Examples
2980
```jldoctest
2981
julia> filter!(isodd, Vector(1:10))
2982
5-element Vector{Int64}:
2983
 1
2984
 3
2985
 5
2986
 7
2987
 9
2988
```
2989
"""
2990
function filter!(f, a::AbstractVector)
1,362,846✔
2991
    j = firstindex(a)
1,362,847✔
2992
    for ai in a
2,793,918✔
2993
        @inbounds a[j] = ai
5,120,605✔
2994
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
5,120,857✔
2995
    end
5,120,605✔
2996
    j > lastindex(a) && return a
2,793,918✔
2997
    if a isa Vector
393✔
2998
        resize!(a, j-1)
393✔
2999
        sizehint!(a, j-1)
393✔
3000
    else
UNCOV
3001
        deleteat!(a, j:lastindex(a))
×
3002
    end
3003
    return a
393✔
3004
end
3005

3006
"""
3007
    filter(f)
3008

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

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

3015
# Examples
3016
```jldoctest
3017
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
3018
(1, 2, 4, 6)
3019

3020
julia> map(filter(iseven), [1:3, 2:4, 3:5])
3021
3-element Vector{Vector{Int64}}:
3022
 [2]
3023
 [2, 4]
3024
 [4]
3025
```
3026
!!! compat "Julia 1.9"
3027
    This method requires at least Julia 1.9.
3028
"""
UNCOV
3029
function filter(f)
×
UNCOV
3030
    Fix1(filter, f)
×
3031
end
3032

3033
"""
3034
    keepat!(a::Vector, inds)
3035
    keepat!(a::BitVector, inds)
3036

3037
Remove the items at all the indices which are not given by `inds`,
3038
and return the modified `a`.
3039
Items which are kept are shifted to fill the resulting gaps.
3040

3041
$(_DOCS_ALIASING_WARNING)
3042

3043
`inds` must be an iterator of sorted and unique integer indices.
3044
See also [`deleteat!`](@ref).
3045

3046
!!! compat "Julia 1.7"
3047
    This function is available as of Julia 1.7.
3048

3049
# Examples
3050
```jldoctest
3051
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
3052
3-element Vector{Int64}:
3053
 6
3054
 4
3055
 2
3056
```
3057
"""
UNCOV
3058
keepat!(a::Vector, inds) = _keepat!(a, inds)
×
3059

3060
"""
3061
    keepat!(a::Vector, m::AbstractVector{Bool})
3062
    keepat!(a::BitVector, m::AbstractVector{Bool})
3063

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

3068
# Examples
3069
```jldoctest
3070
julia> a = [:a, :b, :c];
3071

3072
julia> keepat!(a, [true, false, true])
3073
2-element Vector{Symbol}:
3074
 :a
3075
 :c
3076

3077
julia> a
3078
2-element Vector{Symbol}:
3079
 :a
3080
 :c
3081
```
3082
"""
UNCOV
3083
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
×
3084

3085
# set-like operators for vectors
3086
# These are moderately efficient, preserve order, and remove dupes.
3087

3088
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
98✔
3089
    # P, U force specialization
3090
    if pred(x, state)
314✔
3091
        update!(state, x)
81✔
3092
        true
3093
    else
3094
        false
3095
    end
3096
end
3097

3098
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
2✔
3099
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
85✔
3100

3101
function _grow!(pred!, v::AbstractVector, itrs)
3102
    filter!(pred!, v) # uniquify v
2✔
3103
    for itr in itrs
2✔
3104
        mapfilter(pred!, push!, itr, v)
4✔
3105
    end
6✔
3106
    return v
2✔
3107
end
3108

3109
union!(v::AbstractVector{T}, itrs...) where {T} =
2✔
3110
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3111

UNCOV
3112
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
×
3113
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3114

UNCOV
3115
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
×
UNCOV
3116
    seen = Set{eltype(v)}()
×
UNCOV
3117
    filter!(_grow_filter!(seen), v)
×
UNCOV
3118
    shrinker!(seen, itrs...)
×
UNCOV
3119
    filter!(in(seen), v)
×
3120
end
3121

3122
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
×
3123
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
×
3124

3125
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
85✔
3126

3127
function _shrink(shrinker!::F, itr, itrs) where F
85✔
3128
    T = promote_eltype(itr, itrs...)
85✔
3129
    keep = shrinker!(Set{T}(itr), itrs...)
85✔
3130
    vectorfilter(T, _shrink_filter!(keep), itr)
85✔
3131
end
3132

3133
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
80✔
3134
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
5✔
3135

UNCOV
3136
function intersect(v::AbstractVector, r::AbstractRange)
×
UNCOV
3137
    T = promote_eltype(v, r)
×
UNCOV
3138
    common = Iterators.filter(in(r), v)
×
UNCOV
3139
    seen = Set{T}(common)
×
UNCOV
3140
    return vectorfilter(T, _shrink_filter!(seen), common)
×
3141
end
UNCOV
3142
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
×
3143

3144
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3145
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
819,404✔
3146
    if i isa Bool # Not via dispatch to avoid ambiguities
820,160✔
UNCOV
3147
        throw(ArgumentError("invalid index: $i of type Bool"))
×
3148
    else
3149
        _getindex(v, i)
4,570,423✔
3150
    end
3151
end
3152

3153
"""
3154
    wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
3155

3156
Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version
3157
of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers.
3158
"""
3159
function wrap end
3160

3161
# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller
3162
function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N}
3163
    mem = ref.mem
10,361✔
3164
    mem_len = length(mem) + 1 - memoryrefoffset(ref)
10,361✔
UNCOV
3165
    len = Core.checked_dims(dims...)
×
3166
    @boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len)
10,361✔
3167
    return ref
×
3168
end
3169

UNCOV
3170
@noinline invalid_wrap_err(len, dims, proddims) = throw(DimensionMismatch(LazyString(
×
3171
    "Attempted to wrap a MemoryRef of length ", len, " with an Array of size dims=", dims,
3172
    " which is invalid because prod(dims) = ", proddims, " > ", len,
3173
    " so that the array would have more elements than the underlying memory can store.")))
3174

UNCOV
3175
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
×
3176
    dims = convert(Dims, dims)
×
3177
    ref = _wrap(m, dims)
×
3178
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
×
3179
end
3180

UNCOV
3181
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
×
UNCOV
3182
    dims = convert(Dims, dims)
×
UNCOV
3183
    ref = _wrap(memoryref(m), dims)
×
UNCOV
3184
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
×
3185
end
3186
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
3187
    dims = (Int(l),)
10,361✔
3188
    ref = _wrap(m, dims)
10,361✔
3189
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
2,581✔
3190
end
UNCOV
3191
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
×
UNCOV
3192
    dims = (Int(l),)
×
UNCOV
3193
    ref = _wrap(memoryref(m), (l,))
×
UNCOV
3194
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
×
3195
end
3196
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
3197
    ref = memoryref(m)
3,247✔
3198
    dims = (length(m),)
3,247✔
3199
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
3,169✔
3200
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