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

JuliaLang / julia / #38120

03 Jul 2025 03:51AM UTC coverage: 25.688% (-0.003%) from 25.691%
#38120

push

local

web-flow
Add missing module qualifier (#58877)

A very simple fix addressing the following bug:
```julia
Validation: Error During Test at REPL[61]:1
  Got exception outside of a @test
  #=ERROR showing exception stack=# UndefVarError: `get_ci_mi` not defined in `Base.StackTraces`
  Suggestion: check for spelling errors or missing imports.
  Hint: a global variable of this name also exists in Base.
      - Also declared public in Compiler (loaded but not imported in Main).
  Stacktrace:
    [1] show_custom_spec_sig(io::IOContext{IOBuffer}, owner::Any, linfo::Core.CodeInstance, frame::Base.StackTraces.StackFrame)
      @ Base.StackTraces ./stacktraces.jl:293
    [2] show_spec_linfo(io::IOContext{IOBuffer}, frame::Base.StackTraces.StackFrame)
      @ Base.StackTraces ./stacktraces.jl:278
    [3] print_stackframe(io::IOContext{IOBuffer}, i::Int64, frame::Base.StackTraces.StackFrame, n::Int64, ndigits_max::Int64, modulecolor::Symbol; prefix::Nothing)
      @ Base ./errorshow.jl:786
```

AFAIK this occurs when printing a stacktrace from a `CodeInstance` that
has a non-default owner.

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

1187 existing lines in 8 files now uncovered.

12872 of 50109 relevant lines covered (25.69%)

736460.96 hits per line

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

60.04
/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}()
41,710✔
159
function vect(X::T...) where T
1,074✔
160
    @_terminates_locally_meta
3,312✔
161
    vec = Vector{T}(undef, length(X))
10,447✔
162
    @_safeindex for i = 1:length(X)
3,458✔
163
        vec[i] = X[i]
13,269✔
164
    end
9,029✔
165
    return vec
3,385✔
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...)
7✔
184
    T = promote_typeof(X...)
7✔
185
    return T[X...]
7✔
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,311✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
1,311✔
193
end
194
size(a::Array) = getfield(a, :size)
18,708,604✔
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))
568,865✔
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)
3,038,846✔
217
    @inline
3,105,115✔
218
    @boundscheck checkbounds(A, i)
25,529,768✔
219
    @inbounds _unsetindex!(memoryref(A.ref, i))
26,088,936✔
220
    return A
13,244,286✔
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,034✔
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
3,411,188✔
246
    @inline
3,355,332✔
247
    @_noub_if_noinbounds_meta
3,355,332✔
248
    @boundscheck checkbounds(Bool, a, i) || return false
31,531,414✔
249
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
31,531,414✔
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))
442,813✔
269
    return dest
149,722✔
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)
4,538✔
283
    n == 0 && return dest
79,847✔
284
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
61,416✔
285
    return dest
31,465✔
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)
185✔
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)
1,640,415✔
300

301
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
89,602✔
302
    n == 0 && return dest
1,017,948✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
816,622✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
816,622✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
816,622✔
306
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
816,622✔
307
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
817,338✔
309
    end
310
    return dest
75,288✔
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
_copyto2arg!(dest, src) = copyto!(dest, firstindex(dest), src, firstindex(src), length(src))
196,771✔
320

321
copyto!(dest::Array, src::Array) = _copyto2arg!(dest, src)
164✔
322
copyto!(dest::Array, src::Memory) = _copyto2arg!(dest, src)
×
323
copyto!(dest::Memory, src::Array) = _copyto2arg!(dest, src)
×
324

325
# also to avoid ambiguities in packages
326
copyto!(dest::Array{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
196,607✔
327
copyto!(dest::Array{T}, src::Memory{T}) where {T} = _copyto2arg!(dest, src)
×
328
copyto!(dest::Memory{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
×
329

330
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
331
# for bootstrapping purposes.
332
function fill!(dest::Array{T}, x) where T
362,238✔
333
    @inline
3,009,125✔
334
    x = x isa T ? x : convert(T, x)::T
3,009,557✔
335
    return _fill!(dest, x)
131,538,545✔
336
end
337
function _fill!(dest::Array{T}, x::T) where T
362,238✔
338
    for i in eachindex(dest)
5,861,509✔
339
        @inbounds dest[i] = x
138,859,329✔
340
    end
264,742,541✔
341
    return dest
4,111,156✔
342
end
343

344
"""
345
    copy(x)
346

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

351
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
352
"""
353
copy
354

355
@eval function copy(a::Array)
493,060✔
356
    # `copy` only throws when the size exceeds the max allocation size,
357
    # but since we're copying an existing array, we're guaranteed that this will not happen.
358
    @_nothrow_meta
279,899✔
359
    ref = a.ref
3,071,218✔
360
    newmem = typeof(ref.mem)(undef, length(a))
3,071,218✔
361
    @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a))
4,930,918✔
362
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
3,071,218✔
363
end
364

365
# a mutating version of copyto! that results in dst aliasing src afterwards
366
function _take!(dst::Array{T,N}, src::Array{T,N}) where {T,N}
367
    if getfield(dst, :ref) !== getfield(src, :ref)
407✔
368
        setfield!(dst, :ref, getfield(src, :ref))
×
369
    end
370
    if getfield(dst, :size) !== getfield(src, :size)
407✔
371
        setfield!(dst, :size, getfield(src, :size))
194✔
372
    end
373
    return dst
407✔
374
end
375

376
## Constructors ##
377

378
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
1,234✔
379
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
×
380
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
74✔
381
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
×
382
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
9,236✔
383
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
954,273✔
384
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
×
385

386
# T[x...] constructs Array{T,1}
387
"""
388
    getindex(type[, elements...])
389

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

393
# Examples
394
```jldoctest
395
julia> Int8[1, 2, 3]
396
3-element Vector{Int8}:
397
 1
398
 2
399
 3
400

401
julia> getindex(Int8, 1, 2, 3)
402
3-element Vector{Int8}:
403
 1
404
 2
405
 3
406
```
407
"""
408
function getindex(::Type{T}, vals...) where T
8,033,985✔
409
    @inline
8,174,629✔
410
    @_effect_free_terminates_locally_meta
8,174,629✔
411
    a = Vector{T}(undef, length(vals))
13,630,329✔
412
    if vals isa NTuple
8,174,629✔
413
        @_safeindex for i in 1:length(vals)
8,174,125✔
414
            a[i] = vals[i]
583,300✔
415
        end
92,804✔
416
    else
417
        # use afoldl to avoid type instability inside loop
418
        afoldl(1, vals...) do i, v
507✔
419
            @inbounds a[i] = v
1,536✔
420
            return i + 1
1,536✔
421
        end
422
    end
423
    return a
8,174,654✔
424
end
425

426
function getindex(::Type{Any}, @nospecialize vals...)
478,212✔
427
    @_effect_free_terminates_locally_meta
20,976✔
428
    a = Vector{Any}(undef, length(vals))
509,761✔
429
    @_safeindex for i = 1:length(vals)
262,720✔
430
        a[i] = vals[i]
960,324✔
431
    end
1,096,131✔
432
    return a
480,812✔
433
end
434
getindex(::Type{Any}) = Vector{Any}()
451,033✔
435

436
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
437
    ref = a.ref
68,262✔
438
    t = @_gc_preserve_begin ref
68,262✔
439
    p = unsafe_convert(Ptr{Cvoid}, ref)
68,262✔
440
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
68,262✔
441
    @_gc_preserve_end t
68,262✔
442
    return a
61✔
443
end
444

445
to_dim(d::Integer) = d
×
446
to_dim(d::OneTo) = last(d)
×
447

448
"""
449
    fill(value, dims::Tuple)
450
    fill(value, dims...)
451

452
Create an array of size `dims` with every location set to `value`.
453

454
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
455
with `1.0` in every location of the array.
456

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

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

470
```jldoctest
471
julia> v = fill([], 3)
472
3-element Vector{Vector{Any}}:
473
 []
474
 []
475
 []
476

477
julia> v[1] === v[2] === v[3]
478
true
479

480
julia> value = v[1]
481
Any[]
482

483
julia> push!(value, 867_5309)
484
1-element Vector{Any}:
485
 8675309
486

487
julia> v
488
3-element Vector{Vector{Any}}:
489
 [8675309]
490
 [8675309]
491
 [8675309]
492
```
493

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

497
```jldoctest
498
julia> v2 = [[] for _ in 1:3]
499
3-element Vector{Vector{Any}}:
500
 []
501
 []
502
 []
503

504
julia> v2[1] === v2[2] === v2[3]
505
false
506

507
julia> push!(v2[1], 8675309)
508
1-element Vector{Any}:
509
 8675309
510

511
julia> v2
512
3-element Vector{Vector{Any}}:
513
 [8675309]
514
 []
515
 []
516
```
517

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

520
# Examples
521
```jldoctest
522
julia> fill(1.0, (2,3))
523
2×3 Matrix{Float64}:
524
 1.0  1.0  1.0
525
 1.0  1.0  1.0
526

527
julia> fill(42)
528
0-dimensional Array{Int64, 0}:
529
42
530

531
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
532
2-element Vector{Vector{Float64}}:
533
 [0.0, 0.0]
534
 [0.0, 0.0]
535

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

538
julia> A # both A[1] and A[2] are the very same vector
539
2-element Vector{Vector{Float64}}:
540
 [42.0, 0.0]
541
 [42.0, 0.0]
542
```
543
"""
544
function fill end
545

546
fill(v, dims::DimOrInd...) = fill(v, dims)
97,085,430✔
547
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
548
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
97,085,430✔
549
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
×
550
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
×
551

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

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

559
# Examples
560
```jldoctest
561
julia> zeros(1)
562
1-element Vector{Float64}:
563
 0.0
564

565
julia> zeros(Int8, 2, 3)
566
2×3 Matrix{Int8}:
567
 0  0  0
568
 0  0  0
569
```
570
"""
571
function zeros end
572

573
"""
574
    ones([T=Float64,] dims::Tuple)
575
    ones([T=Float64,] dims...)
576

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

580
# Examples
581
```jldoctest
582
julia> ones(1,2)
583
1×2 Matrix{Float64}:
584
 1.0  1.0
585

586
julia> ones(ComplexF64, 2, 3)
587
2×3 Matrix{ComplexF64}:
588
 1.0+0.0im  1.0+0.0im  1.0+0.0im
589
 1.0+0.0im  1.0+0.0im  1.0+0.0im
590
```
591
"""
592
function ones end
593

594
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
595
    @eval begin
596
        $fname(dims::DimOrInd...) = $fname(dims)
×
597
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
13,252,944✔
598
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
×
599
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
×
600
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
53,034✔
601
            a = Array{T,N}(undef, dims)
868,162✔
602
            fill!(a, $felt(T))
13,252,944✔
603
            return a
799,961✔
604
        end
605
        function $fname(::Type{T}, dims::Tuple{}) where {T}
×
606
            a = Array{T}(undef)
×
607
            fill!(a, $felt(T))
×
608
            return a
×
609
        end
610
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
×
611
            a = similar(Array{T,N}, dims)
×
612
            fill!(a, $felt(T))
×
613
            return a
×
614
        end
615
    end
616
end
617

618
## Conversions ##
619

620
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
164✔
621

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

624
## Constructors ##
625

626
# constructors should make copies
627
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
164✔
628
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
×
629

630
## copying iterators to containers
631

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

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

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

649
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
×
650
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
651
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
236,804✔
652
    a = Vector{T}()
236,804✔
653
    for x in itr
236,822✔
654
        push!(a, x)
1,249,247✔
655
    end
1,249,263✔
656
    return a
236,804✔
657
end
658

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

662
_similar_shape(itr, ::SizeUnknown) = nothing
×
663
_similar_shape(itr, ::HasLength) = length(itr)::Integer
270,687✔
664
_similar_shape(itr, ::HasShape) = axes(itr)
3,334,073✔
665

666
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
2,019✔
667
    similar(c, T, 0)
668
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
38,858✔
669
    similar(c, T, len)
670
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
211✔
671
    similar(c, T, axs)
672

673
# make a collection appropriate for collecting `itr::Generator`
674
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
×
675
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
208,718✔
676
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
5,965,631✔
677

678
# used by syntax lowering for simple typed comprehensions
679
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
6,190,810✔
680

681

682
"""
683
    collect(iterator)
684

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

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

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

697
# Examples
698

699
Collect items from a `UnitRange{Int64}` collection:
700

701
```jldoctest
702
julia> collect(1:3)
703
3-element Vector{Int64}:
704
 1
705
 2
706
 3
707
```
708

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

711
```jldoctest
712
julia> collect(x^2 for x in 1:3)
713
3-element Vector{Int64}:
714
 1
715
 4
716
 9
717
```
718

719
Collecting an empty iterator where the result type depends on type inference:
720

721
```jldoctest
722
julia> [rand(Bool) ? 1 : missing for _ in []]
723
Union{Missing, Int64}[]
724
```
725

726
When the iterator is non-empty, the result type depends only on values:
727

728
```julia-repl
729
julia> [rand(Bool) ? 1 : missing for _ in [""]]
730
1-element Vector{Int64}:
731
 1
732
```
733
"""
734
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
311,766✔
735

736
collect(A::AbstractArray) = _collect_indices(axes(A), A)
×
737

738
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
219✔
739

740
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
44,819✔
741
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
742

743
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
2,019✔
744
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
2,019✔
745
    for x in itr
4,028✔
746
        push!(a,x)
21,138✔
747
    end
40,002✔
748
    return a
2,019✔
749
end
750

751
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
×
752
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
×
753
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
754
function _collect_indices(indsA, A)
×
755
    B = Array{eltype(A)}(undef, length.(indsA))
×
756
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
×
757
end
758

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

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

789
function collect(itr::Generator)
1,176✔
790
    isz = IteratorSize(itr.iter)
1,379✔
791
    et = @default_eltype(itr)
792
    if isa(isz, SizeUnknown)
1,379✔
793
        return grow_to!(Vector{et}(), itr)
660✔
794
    else
795
        shp = _similar_shape(itr, isz)
719✔
796
        y = iterate(itr)
1,434✔
797
        if y === nothing
719✔
798
            return _array_for(et, isz, shp)
4✔
799
        end
800
        v1, st = y
715✔
801
        dest = _array_for(typeof(v1), isz, shp)
715✔
802
        # The typeassert gives inference a helping hand on the element type and dimensionality
803
        # (work-around for #28382)
804
        et′ = et <: Type ? Type : et
715✔
805
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
715✔
806
        collect_to_with_first!(dest, v1, itr, st)::RT
715✔
807
    end
808
end
809

810
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
×
811
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
×
812

813
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
202✔
814
    et = @default_eltype(itr)
209✔
815
    shp = _similar_shape(itr, isz)
211✔
816
    y = iterate(itr)
416✔
817
    if y === nothing
211✔
818
        return _similar_for(c, et, itr, isz, shp)
3✔
819
    end
820
    v1, st = y
206✔
821
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
208✔
822
    # The typeassert gives inference a helping hand on the element type and dimensionality
823
    # (work-around for #28382)
824
    et′ = et <: Type ? Type : et
206✔
825
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
206✔
826
    collect_to_with_first!(dest, v1, itr, st)::RT
208✔
827
end
828

829
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
32✔
830
    i1 = first(LinearIndices(dest))
902✔
831
    dest[i1] = v1
924✔
832
    return collect_to!(dest, itr, i1+1, st)
1,100✔
833
end
834

835
function collect_to_with_first!(dest, v1, itr, st)
×
836
    push!(dest, v1)
×
837
    return grow_to!(dest, itr, st)
×
838
end
839

840
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
×
841
    @inline
×
842
    new = similar(dest, promote_typejoin(T, typeof(el)))
×
843
    f = first(LinearIndices(dest))
×
844
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
×
845
    @inbounds new[i] = el
×
846
    return new
×
847
end
848

849
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
436✔
850
    # collect to dest array, checking the type of each result. if a result does not
851
    # match, widen the result type and re-dispatch.
852
    i = offs
919✔
853
    while true
8,877✔
854
        y = iterate(itr, st)
16,374✔
855
        y === nothing && break
8,877✔
856
        el, st = y
7,777✔
857
        if el isa T
7,777✔
858
            @inbounds dest[i] = el
7,953✔
859
            i += 1
7,953✔
860
        else
861
            new = setindex_widen_up_to(dest, el, i)
×
862
            return collect_to!(new, itr, i+1, st)
×
863
        end
864
    end
7,953✔
865
    return dest
924✔
866
end
867

868
function grow_to!(dest, itr)
2✔
869
    y = iterate(itr)
660✔
870
    y === nothing && return dest
660✔
871
    dest2 = empty(dest, typeof(y[1]))
×
872
    push!(dest2, y[1])
×
873
    grow_to!(dest2, itr, y[2])
×
874
end
875

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

889
function grow_to!(dest, itr, st)
×
890
    T = eltype(dest)
×
891
    y = iterate(itr, st)
×
892
    while y !== nothing
×
893
        el, st = y
×
894
        if el isa T
×
895
            push!(dest, el)
×
896
        else
897
            new = push_widen(dest, el)
×
898
            return grow_to!(new, itr, st)
×
899
        end
900
        y = iterate(itr, st)
×
901
    end
×
902
    return dest
×
903
end
904

905
## Indexing: getindex ##
906

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

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

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

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

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

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

934
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
935
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
79,796✔
936
    @inline
77,432✔
937
    @boundscheck checkbounds(A, I)
953,763✔
938
    lI = length(I)
953,763✔
939
    X = similar(A, axes(I))
953,763✔
940
    if lI > 0
953,763✔
941
        copyto!(X, firstindex(X), A, first(I), lI)
901,302✔
942
    end
943
    return X
948,698✔
944
end
945

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

949
function getindex(A::Array, c::Colon)
198✔
950
    lI = length(A)
9,236✔
951
    X = similar(A, lI)
9,236✔
952
    if lI > 0
9,236✔
953
        unsafe_copyto!(X, 1, A, 1, lI)
18,274✔
954
    end
955
    return X
9,236✔
956
end
957

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

963
## Indexing: setindex! ##
964

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

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

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

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

985
function setindex!(A::Array{T}, x, i::Int) where {T}
56,926,613✔
986
    @_propagate_inbounds_meta
57,204,916✔
987
    x = x isa T ? x : convert(T, x)::T
61,097,794✔
988
    return _setindex!(A, x, i)
449,511,353✔
989
end
990
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
56,926,097✔
991
    @_noub_if_noinbounds_meta
57,204,759✔
992
    @boundscheck checkbounds(Bool, A, i) || throw_boundserror(A, (i,))
449,511,382✔
993
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
449,511,382✔
994
    return A
305,165,215✔
995
end
UNCOV
996
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
×
UNCOV
997
    @_propagate_inbounds_meta
×
UNCOV
998
    x = x isa T ? x : convert(T, x)::T
×
UNCOV
999
    return _setindex!(A, x, i1, i2, I...)
×
1000
end
1001
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
×
1002
    @inline
×
1003
    @_noub_if_noinbounds_meta
×
UNCOV
1004
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
×
1005
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
×
1006
    return A
×
1007
end
1008

1009
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
268,559✔
1010
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
2,931,444✔
1011
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
11,206,901✔
1012
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
24,498,665✔
UNCOV
1013
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
×
UNCOV
1014
    __safe_setindex!(A, convert(T, x)::T, i))
×
1015

1016
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1017
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
71,375✔
1018
    @_propagate_inbounds_meta
71,376✔
1019
    @boundscheck setindex_shape_check(X, length(I))
71,376✔
1020
    @boundscheck checkbounds(A, I)
71,376✔
1021
    require_one_based_indexing(X)
71,376✔
1022
    X′ = unalias(A, X)
71,376✔
1023
    I′ = unalias(A, I)
71,376✔
1024
    count = 1
71,376✔
1025
    for i in I′
121,833✔
1026
        @inbounds A[i] = X′[count]
177,330✔
1027
        count += 1
177,330✔
1028
    end
267,597✔
1029
    return A
71,376✔
1030
end
1031

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

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

1069
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
8,599,773✔
1070

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

1106
function _growbeg!(a::Vector, delta::Integer)
59,624✔
1107
    @_noub_meta
59,625✔
1108
    delta = Int(delta)
59,625✔
1109
    delta == 0 && return # avoid attempting to index off the end
195,009✔
1110
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
195,006✔
1111
    ref = a.ref
641,017✔
1112
    mem = ref.mem
59,625✔
1113
    len = length(a)
641,017✔
1114
    offset = memoryrefoffset(ref)
641,017✔
1115
    newlen = len + delta
641,017✔
1116
    setfield!(a, :size, (newlen,))
641,017✔
1117
    # if offset is far enough advanced to fit data in existing memory without copying
1118
    if delta <= offset - 1
641,017✔
1119
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
473,401✔
1120
    else
1121
        @noinline _growbeg_internal!(a, delta, len)
167,616✔
1122
    end
1123
    return
639,241✔
1124
end
1125

1126
function _growend_internal!(a::Vector, delta::Int, len::Int)
8,393,222✔
1127
    ref = a.ref
8,393,222✔
1128
    mem = ref.mem
8,393,222✔
1129
    memlen = length(mem)
8,393,222✔
1130
    newlen = len + delta
8,393,222✔
1131
    offset = memoryrefoffset(ref)
8,393,222✔
1132
    newmemlen = offset + newlen - 1
8,393,222✔
1133
    if offset + len - 1 > memlen || offset < 1
16,786,444✔
UNCOV
1134
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1135
    end
1136

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

1161
function _growend!(a::Vector, delta::Integer)
7,543,742✔
1162
    @_noub_meta
8,390,747✔
1163
    delta = Int(delta)
8,390,747✔
1164
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
16,704,781✔
1165
    ref = a.ref
30,793,965✔
1166
    mem = ref.mem
30,793,965✔
1167
    memlen = length(mem)
30,793,965✔
1168
    len = length(a)
30,793,965✔
1169
    newlen = len + delta
30,793,965✔
1170
    offset = memoryrefoffset(ref)
30,793,965✔
1171
    setfield!(a, :size, (newlen,))
30,793,965✔
1172
    newmemlen = offset + newlen - 1
30,793,965✔
1173
    if memlen < newmemlen
30,793,965✔
1174
        @noinline _growend_internal!(a, delta, len)
8,397,641✔
1175
    end
1176
    return
29,274,043✔
1177
end
1178

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

1196
    # which side would we rather grow into?
1197
    prefer_start = i <= div(len, 2)
821,355✔
1198
    # if offset is far enough advanced to fit data in beginning of the memory
1199
    if prefer_start && delta <= offset - 1
821,355✔
1200
        newref = @inbounds memoryref(mem, offset - delta)
359,402✔
1201
        unsafe_copyto!(newref, ref, i)
631,486✔
1202
        setfield!(a, :ref, newref)
359,402✔
1203
        for j in i:i+delta-1
359,402✔
1204
            @inbounds _unsetindex!(a, j)
504,172✔
1205
        end
504,172✔
1206
    elseif !prefer_start && memlen >= newmemlen
461,953✔
1207
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
739,360✔
1208
        for j in i:i+delta-1
422,049✔
1209
            @inbounds _unsetindex!(a, j)
589,913✔
1210
        end
589,913✔
1211
    else
1212
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1213
        # the +1 is because I didn't want to have an off by 1 error.
1214
        newmemlen = max(overallocation(memlen), len+2*delta+1)
54,100✔
1215
        newoffset = (newmemlen - newlen) ÷ 2 + 1
39,904✔
1216
        newmem = array_new_memory(mem, newmemlen)
39,904✔
1217
        newref = @inbounds memoryref(newmem, newoffset)
39,904✔
1218
        unsafe_copyto!(newref, ref, i-1)
75,288✔
1219
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
75,288✔
1220
        setfield!(a, :ref, newref)
39,904✔
1221
    end
1222
end
1223

1224
# efficiently delete part of an array
1225
function _deletebeg!(a::Vector, delta::Integer)
252,023✔
1226
    delta = Int(delta)
317,230✔
1227
    len = length(a)
962,429✔
1228
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
962,429✔
1229
    for i in 1:delta
318,912✔
1230
        @inbounds _unsetindex!(a, i)
1,131,534✔
1231
    end
338,408✔
1232
    newlen = len - delta
962,429✔
1233
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
962,429✔
1234
        newref = @inbounds memoryref(a.ref, delta + 1)
767,205✔
1235
        setfield!(a, :ref, newref)
767,205✔
1236
    end
1237
    setfield!(a, :size, (newlen,))
962,429✔
1238
    return
962,429✔
1239
end
1240
function _deleteend!(a::Vector, delta::Integer)
1,959,832✔
1241
    delta = Int(delta)
1,960,125✔
1242
    len = length(a)
14,701,115✔
1243
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
14,701,115✔
1244
    newlen = len - delta
14,701,115✔
1245
    for i in newlen+1:len
14,916,613✔
1246
        @inbounds _unsetindex!(a, i)
23,863,317✔
1247
    end
31,532,939✔
1248
    setfield!(a, :size, (newlen,))
14,701,115✔
1249
    return
14,627,586✔
1250
end
1251
function _deleteat!(a::Vector, i::Integer, delta::Integer)
70,089✔
1252
    i = Int(i)
70,089✔
1253
    len = length(a)
70,089✔
1254
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
70,089✔
1255
    1 <= i <= len || throw(BoundsError(a, i))
70,089✔
1256
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
70,089✔
1257
    newa = a
70,089✔
1258
    if 2*i + delta <= len
70,089✔
1259
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
1,720✔
1260
        _deletebeg!(a, delta)
1,674✔
1261
    else
1262
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
89,012✔
1263
        _deleteend!(a, delta)
68,415✔
1264
    end
1265
    return
70,089✔
1266
end
1267
## Dequeue functionality ##
1268

1269
"""
1270
    push!(collection, items...) -> collection
1271

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

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

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

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

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

1297
function push!(a::Vector{T}, item) where T
6,987,408✔
1298
    @inline
11,110,229✔
1299
    # convert first so we don't grow the array if the assignment won't work
1300
    # and also to avoid a dynamic dynamic dispatch in the common case that
1301
    # `item` is poorly-typed and `a` is well-typed
1302
    item = item isa T ? item : convert(T, item)::T
11,545,799✔
1303
    return _push!(a, item)
23,902,090✔
1304
end
1305
function _push!(a::Vector{T}, item::T) where T
6,987,194✔
1306
    _growend!(a, 1)
23,902,090✔
1307
    @_safeindex a[length(a)] = item
23,902,090✔
1308
    return a
23,885,975✔
1309
end
1310

1311
# specialize and optimize the single argument case
1312
function push!(a::Vector{Any}, @nospecialize x)
859,397✔
1313
    _growend!(a, 1)
1,482,944✔
1314
    @_safeindex a[length(a)] = x
1,482,944✔
1315
    return a
1,482,944✔
1316
end
1317
function push!(a::Vector{Any}, @nospecialize x...)
432✔
1318
    @_terminates_locally_meta
432✔
1319
    na = length(a)
1,695✔
1320
    nx = length(x)
432✔
1321
    _growend!(a, nx)
1,695✔
1322
    @_safeindex for i = 1:nx
2,958✔
1323
        a[na+i] = x[i]
3,390✔
1324
    end
4,653✔
1325
    return a
1,695✔
1326
end
1327

1328
"""
1329
    append!(collection, collections...) -> collection.
1330

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

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

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

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

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

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

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

1366
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
46,501✔
1367
    items isa Tuple && (items = map(x -> convert(T, x), items))
48,520✔
1368
    n = Int(length(items))::Int
388,794✔
1369
    _growend!(a, n)
388,796✔
1370
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
543,049✔
1371
    return a
388,793✔
1372
end
1373

1374
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
1,110,307✔
1375
push!(a::AbstractVector, iter...) = append!(a, iter)
1,911✔
UNCOV
1376
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
×
1377

1378
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
213,484✔
1379
    n = Int(length(iter))::Int
218,253✔
1380
    i = lastindex(a)
213,484✔
1381
    sizehint!(a, length(a) + n; shrink=false)
213,484✔
1382
    for item in iter
307,809✔
1383
        push!(a, item)
832,941✔
1384
    end
904,543✔
1385
    a
213,484✔
1386
end
1387
function _append!(a::AbstractVector, ::IteratorSize, iter)
896,823✔
1388
    for item in iter
1,007,979✔
1389
        push!(a, item)
1,001,026✔
1390
    end
1,010,038✔
1391
    a
896,823✔
1392
end
1393

1394
"""
1395
    prepend!(a::Vector, collections...) -> collection
1396

1397
Insert the elements of each `collections` to the beginning of `a`.
1398

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

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

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

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

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

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

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

1462
"""
1463
    resize!(a::Vector, n::Integer) -> a
1464

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

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

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

1479
julia> length(a)
1480
8
1481

1482
julia> a[1:6]
1483
6-element Vector{Int64}:
1484
 6
1485
 5
1486
 4
1487
 3
1488
 2
1489
 1
1490
```
1491
"""
1492
function resize!(a::Vector, nl_::Integer)
5,679,234✔
1493
    nl = Int(nl_)::Int
5,679,278✔
1494
    l = length(a)
5,978,398✔
1495
    if nl > l
5,978,398✔
1496
        _growend!(a, nl-l)
3,399,478✔
1497
    elseif nl != l
2,578,920✔
1498
        if nl < 0
679,172✔
UNCOV
1499
            _throw_argerror("new length must be ≥ 0")
×
1500
        end
1501
        _deleteend!(a, l-nl)
679,172✔
1502
    end
1503
    return a
5,978,398✔
1504
end
1505

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

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

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

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

1522
See also [`resize!`](@ref).
1523

1524
# Notes on the performance model
1525

1526
For types that support `sizehint!`,
1527

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

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

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

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

1542
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
491,042✔
1543
    len = length(a)
244,399✔
1544
    ref = a.ref
244,399✔
1545
    mem = ref.mem
244,399✔
1546
    memlen = length(mem)
244,399✔
1547
    sz = max(Int(sz), len)
244,399✔
1548
    inc = sz - len
244,399✔
1549
    if sz <= memlen
244,399✔
1550
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1551
        if !shrink || memlen - sz <= div(memlen, 8)
173,097✔
1552
            return a
172,035✔
1553
        end
1554
        newmem = array_new_memory(mem, sz)
597✔
1555
        if first
465✔
UNCOV
1556
            newref = memoryref(newmem, inc + 1)
×
1557
        else
1558
            newref = memoryref(newmem)
465✔
1559
        end
1560
        unsafe_copyto!(newref, ref, len)
692✔
1561
        setfield!(a, :ref, newref)
465✔
1562
    elseif first
71,899✔
UNCOV
1563
        _growbeg!(a, inc)
×
UNCOV
1564
        newref = getfield(a, :ref)
×
UNCOV
1565
        newref = memoryref(newref, inc + 1)
×
UNCOV
1566
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
×
1567
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
×
1568
    else # last
1569
        _growend!(a, inc)
71,899✔
1570
        setfield!(a, :size, (len,)) # undo the size change from _growend!
71,899✔
1571
    end
1572
    a
72,364✔
1573
end
1574

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

1584
"""
1585
    pop!(collection) -> item
1586

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

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

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

1601
julia> pop!(A)
1602
3
1603

1604
julia> A
1605
2-element Vector{Int64}:
1606
 1
1607
 2
1608

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

1614
julia> pop!(S)
1615
2
1616

1617
julia> S
1618
Set{Int64} with 1 element:
1619
  1
1620

1621
julia> pop!(Dict(1=>2))
1622
1 => 2
1623
```
1624
"""
1625
function pop!(a::Vector)
1,889,501✔
1626
    if isempty(a)
13,580,142✔
UNCOV
1627
        _throw_argerror("array must be non-empty")
×
1628
    end
1629
    item = a[end]
13,580,142✔
1630
    _deleteend!(a, 1)
13,580,142✔
1631
    return item
13,506,613✔
1632
end
1633

1634
"""
1635
    popat!(a::Vector, i::Integer, [default])
1636

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

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

1644
!!! compat "Julia 1.5"
1645
    This function is available as of Julia 1.5.
1646

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

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

1658
julia> popat!(a, 4, missing)
1659
missing
1660

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

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

1683
"""
1684
    pushfirst!(collection, items...) -> collection
1685

1686
Insert one or more `items` at the beginning of `collection`.
1687

1688
This function is called `unshift` in many other programming languages.
1689

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

1713
# specialize and optimize the single argument case
1714
function pushfirst!(a::Vector{Any}, @nospecialize x)
42,998✔
1715
    _growbeg!(a, 1)
501,976✔
1716
    @_safeindex a[1] = x
489,004✔
1717
    return a
489,004✔
1718
end
1719
function pushfirst!(a::Vector{Any}, @nospecialize x...)
UNCOV
1720
    @_terminates_locally_meta
×
UNCOV
1721
    na = length(a)
×
UNCOV
1722
    nx = length(x)
×
UNCOV
1723
    _growbeg!(a, nx)
×
1724
    @_safeindex for i = 1:nx
×
1725
        a[i] = x[i]
×
1726
    end
×
1727
    return a
×
1728
end
1729

1730
"""
1731
    popfirst!(collection) -> item
1732

1733
Remove the first `item` from `collection`.
1734

1735
This function is called `shift` in many other programming languages.
1736

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

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

1750
julia> popfirst!(A)
1751
1
1752

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

1771
"""
1772
    insert!(a::Vector, index::Integer, item)
1773

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

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

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

1806
"""
1807
    deleteat!(a::Vector, i::Integer)
1808

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

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

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

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

1843
"""
1844
    deleteat!(a::Vector, inds)
1845

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

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

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

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

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

1875
struct Nowhere; end
1876
push!(::Nowhere, _) = nothing
96✔
UNCOV
1877
_growend!(::Nowhere, _) = nothing
×
1878

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

1888
function _copy_item!(a::Vector, p, q)
112✔
1889
    @_propagate_inbounds_meta
112✔
1890
    if isassigned(a, q)
463✔
1891
        a[p] = a[q]
463✔
1892
    else
UNCOV
1893
        _unsetindex!(a, p)
×
1894
    end
1895
end
1896

1897
function _deleteat!(a::Vector, inds, dltd=Nowhere())
902✔
1898
    n = length(a)
1,492✔
1899
    y = iterate(inds)
746✔
1900
    y === nothing && return a
746✔
1901
    (p, s) = y
741✔
1902
    checkbounds(a, p)
741✔
1903
    @inbounds _push_deleted!(dltd, a, p)
741✔
1904
    q = p+1
741✔
1905
    while true
884✔
1906
        y = iterate(inds, s)
884✔
1907
        y === nothing && break
884✔
1908
        (i,s) = y
143✔
1909
        if !(q <= i <= n)
143✔
UNCOV
1910
            if i < q
×
UNCOV
1911
                _throw_argerror("indices must be unique and sorted")
×
1912
            else
UNCOV
1913
                throw(BoundsError())
×
1914
            end
1915
        end
1916
        while q < i
231✔
1917
            @inbounds _copy_item!(a, p, q)
88✔
1918
            p += 1; q += 1
88✔
1919
        end
88✔
1920
        @inbounds _push_deleted!(dltd, a, i)
143✔
1921
        q = i+1
143✔
1922
    end
143✔
1923
    while q <= n
1,116✔
1924
        @inbounds _copy_item!(a, p, q)
375✔
1925
        p += 1; q += 1
375✔
1926
    end
375✔
1927
    _deleteend!(a, n-p+1)
848✔
1928
    return a
741✔
1929
end
1930

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

1944
const _default_splice = []
1945

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

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

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

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

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

1969
julia> splice!(A, 5, -1)
1970
1
1971

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

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

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

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

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

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

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

2027
$(_DOCS_ALIASING_WARNING)
2028

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

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

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

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

2060
    n = length(a)
192,604✔
2061
    f = first(r)
192,604✔
2062
    l = last(r)
192,604✔
2063
    d = length(r)
192,604✔
2064

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

2072
    k = 1
192,604✔
2073
    for x in ins
192,604✔
2074
        a[f+k-1] = x
577,812✔
2075
        k += 1
577,812✔
2076
    end
727,744✔
2077
    return v
192,604✔
2078
end
2079

UNCOV
2080
splice!(a::Vector, inds) = (dltds = eltype(a)[]; _deleteat!(a, inds, dltds); dltds)
×
2081

2082
function empty!(a::Vector)
37,438✔
2083
    _deleteend!(a, length(a))
560,071✔
2084
    return a
436,719✔
2085
end
2086

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

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

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

2139
"""
2140
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2141

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

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

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

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

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

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

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

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

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

2221
In-place version of [`reverse`](@ref).
2222

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

2233
julia> reverse!(A);
2234

2235
julia> A
2236
5-element Vector{Int64}:
2237
 5
2238
 4
2239
 3
2240
 2
2241
 1
2242
```
2243
"""
2244
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
1,142,352✔
2245
    s, n = Int(start), Int(stop)
1,949,030✔
2246
    if n > s # non-empty and non-trivial
1,018,946✔
2247
        liv = LinearIndices(v)
293,000✔
2248
        if !(first(liv) ≤ s ≤ last(liv))
293,000✔
UNCOV
2249
            throw(BoundsError(v, s))
×
2250
        elseif !(first(liv) ≤ n ≤ last(liv))
293,000✔
UNCOV
2251
            throw(BoundsError(v, n))
×
2252
        end
2253
        r = n
293,000✔
2254
        @inbounds for i in s:midpoint(s, n-1)
293,000✔
2255
            v[i], v[r] = v[r], v[i]
301,264✔
2256
            r -= 1
301,264✔
2257
        end
309,528✔
2258
    end
2259
    return v
1,018,946✔
2260
end
2261

2262
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2263

UNCOV
2264
vcat() = Vector{Any}()
×
UNCOV
2265
hcat() = Vector{Any}()
×
2266

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

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

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

2297
## find ##
2298

2299
"""
2300
    findnext(A, i)
2301

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

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

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

2317
julia> findnext(A, 1)
2318
3
2319

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

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

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

2333
"""
2334
    findfirst(A)
2335

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

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

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

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

2354
julia> findfirst(A)
2355
3
2356

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

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

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

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

2373
"""
2374
    findnext(predicate::Function, A, i)
2375

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

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

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

2388
julia> findnext(isodd, A, 1)
2389
1
2390

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

2393
julia> A = [1 4; 2 2];
2394

2395
julia> findnext(isodd, A, CartesianIndex(1, 1))
2396
CartesianIndex(1, 1)
2397

2398
julia> findnext(isspace, "a b c", 3)
2399
4
2400
```
2401
"""
2402
function findnext(testf::Function, A, start)
246,415✔
2403
    i = oftype(first(keys(A)), start)
248,039✔
2404
    l = last(keys(A))
1,146,065✔
2405
    i > l && return nothing
1,146,065✔
2406
    while true
676,184✔
2407
        testf(A[i]) && return i
690,329✔
2408
        i == l && break
608,035✔
2409
        # nextind(A, l) can throw/overflow
2410
        i = nextind(A, i)
409,966✔
2411
    end
409,966✔
2412
    return nothing
198,069✔
2413
end
2414

2415
"""
2416
    findfirst(predicate::Function, A)
2417

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

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

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

2433
julia> findfirst(iseven, A)
2434
2
2435

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

2438
julia> findfirst(isequal(4), A)
2439
2
2440

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

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

2457
# Needed for bootstrap, and allows defining only an optimized findnext method
2458
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
2,237,024✔
2459
    findnext(testf, A, first(keys(A)))
2460

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

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

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

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

2481
findfirst(::typeof(iszero), r::AbstractRange) = findfirst(==(zero(first(r))), r)
×
2482
findfirst(::typeof(isone), r::AbstractRange) = findfirst(==(one(first(r))), r)
×
2483

2484
"""
2485
    findprev(A, i)
2486

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

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

2493
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2494

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

2504
julia> findprev(A, 3)
2505
3
2506

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

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

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

2520
"""
2521
    findlast(A)
2522

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

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

2529
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2530

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

2540
julia> findlast(A)
2541
3
2542

2543
julia> A = falses(2,2);
2544

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

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

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

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

2561
"""
2562
    findprev(predicate::Function, A, i)
2563

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

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

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

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

2583
julia> findprev(isodd, A, 3)
2584
3
2585

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

2591
julia> findprev(isodd, A, CartesianIndex(1, 2))
2592
CartesianIndex(2, 1)
2593

2594
julia> findprev(isspace, "a b c", 3)
2595
2
2596
```
2597
"""
2598
function findprev(testf::Function, A, start)
102✔
2599
    f = first(keys(A))
163✔
2600
    i = oftype(f, start)
163✔
2601
    i < f && return nothing
163✔
2602
    while true
585✔
2603
        testf(A[i]) && return i
869✔
2604
        i == f && break
425✔
2605
        # prevind(A, f) can throw/underflow
2606
        i = prevind(A, i)
422✔
2607
    end
422✔
2608
    return nothing
3✔
2609
end
2610

2611
"""
2612
    findlast(predicate::Function, A)
2613

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

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

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

2629
julia> findlast(isodd, A)
2630
3
2631

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

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

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

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

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

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

2665
"""
2666
    findall(f::Function, A)
2667

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

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

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

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

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

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

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

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

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

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

2725
"""
2726
    findall(A)
2727

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

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

2735
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2736

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

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

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

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

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

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

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

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

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

2795
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2796

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

2801
julia> b = ['a', 'b', 'c'];
2802

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

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

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

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

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

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

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

2919
## Filter ##
2920

2921
"""
2922
    filter(f, a)
2923

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

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

2930
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2931

2932
# Examples
2933
```jldoctest
2934
julia> a = 1:10
2935
1:10
2936

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

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

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

2975
"""
2976
    filter!(f, a)
2977

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

2981
# Examples
2982
```jldoctest
2983
julia> filter!(isodd, Vector(1:10))
2984
5-element Vector{Int64}:
2985
 1
2986
 3
2987
 5
2988
 7
2989
 9
2990
```
2991
"""
2992
function filter!(f, a::AbstractVector)
763,815✔
2993
    j = firstindex(a)
763,816✔
2994
    for ai in a
1,600,432✔
2995
        @inbounds a[j] = ai
2,966,797✔
2996
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
2,966,972✔
2997
    end
2,966,797✔
2998
    j > lastindex(a) && return a
1,600,432✔
2999
    if a isa Vector
327✔
3000
        resize!(a, j-1)
327✔
3001
        sizehint!(a, j-1)
327✔
3002
    else
UNCOV
3003
        deleteat!(a, j:lastindex(a))
×
3004
    end
3005
    return a
327✔
3006
end
3007

3008
"""
3009
    filter(f)
3010

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

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

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

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

3035
"""
3036
    keepat!(a::Vector, inds)
3037
    keepat!(a::BitVector, inds)
3038

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

3043
$(_DOCS_ALIASING_WARNING)
3044

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

3048
!!! compat "Julia 1.7"
3049
    This function is available as of Julia 1.7.
3050

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

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

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

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

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

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

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

3090
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
176✔
3091
    # P, U force specialization
3092
    if pred(x, state)
404✔
3093
        update!(state, x)
82✔
3094
        true
3095
    else
3096
        false
3097
    end
3098
end
3099

3100
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
2✔
3101
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
86✔
3102

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

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

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

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

3124
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
×
3125
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
×
3126

3127
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
86✔
3128

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

3135
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
81✔
3136
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
5✔
3137

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

3146
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3147
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
424,506✔
3148
    if i isa Bool # Not via dispatch to avoid ambiguities
425,265✔
UNCOV
3149
        throw(ArgumentError("invalid index: $i of type Bool"))
×
3150
    else
3151
        _getindex(v, i)
2,931,326✔
3152
    end
3153
end
3154

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

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

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

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

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

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