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

JuliaLang / julia / 1649

26 Mar 2026 12:39AM UTC coverage: 77.623% (+0.8%) from 76.798%
1649

push

buildkite

web-flow
Make `SourceRef` contain `Ref{SourceFile}` instead of `SourceFile` (#61402)

64568 of 83181 relevant lines covered (77.62%)

23641174.62 hits per line

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

94.11
/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
11,967✔
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}()
713,030✔
159
function vect(X::T...) where T
32,082✔
160
    @_terminates_locally_meta
37,436,228✔
161
    vec = Vector{T}(undef, length(X))
37,468,462✔
162
    @_safeindex for i = 1:length(X)
37,515,682✔
163
        vec[i] = X[i]
184,724,825✔
164
    end
331,977,199✔
165
    return vec
37,465,472✔
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...)
167,206✔
184
    T = promote_typeof(X...)
168,154✔
185
    return T[X...]
168,652✔
186
end
187

188
asize_from(a::Array, n) = n > ndims(a) ? () : (size(a,n), asize_from(a, n+1)...)
×
189

190
allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0))
51,259✔
191

192
"""
193
    Base.isbitsunion(::Type{T})
194

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

197
# Examples
198
```jldoctest
199
julia> Base.isbitsunion(Union{Float64, UInt8})
200
true
201

202
julia> Base.isbitsunion(Union{Float64, String})
203
false
204
```
205
"""
206
isbitsunion(u::Type) = u isa Union && allocatedinline(u)
6✔
207

208
function _unsetindex!(A::Array, i::Int)
112✔
209
    @inline
257,193,355✔
210
    @boundscheck checkbounds(A, i)
284,680,769✔
211
    @inbounds _unsetindex!(memoryref(A.ref, i))
286,532,141✔
212
    return A
259,598,633✔
213
end
214

215

216
# TODO: deprecate this (aligned_sizeof and/or elsize and/or sizeof(Some{T}) are more correct)
217
elsize(::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
232,121,631✔
218
function elsize(::Type{Ptr{T}}) where T
21✔
219
    # this only must return something valid for values which satisfy is_valid_intrinsic_elptr(T),
220
    # which includes Any and most concrete datatypes
221
    T === Any && return sizeof(Ptr{Any})
21✔
222
    T isa DataType || sizeof(Any) # throws
21✔
223
    return LLT_ALIGN(Core.sizeof(T), datatype_alignment(T))
15✔
224
end
225
elsize(::Type{Union{}}, slurp...) = 0
×
226

227
sizeof(a::Array) = length(a) * elsize(typeof(a)) # n.b. this ignores bitsunion bytes, as a historical fact
211,805✔
228

229
function isassigned(a::Array, i::Int...)
138,895✔
230
    @inline
1,145,692✔
231
    @_noub_if_noinbounds_meta
1,145,692✔
232
    @boundscheck checkbounds(Bool, a, i...) || return false
1,145,722✔
233
    ii = _sub2ind(size(a), i...)
1,145,662✔
234
    return @inbounds isassigned(memoryrefnew(a.ref, ii, false))
1,145,662✔
235
end
236

237
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
265✔
238
    @inline
136,184,064✔
239
    @_noub_if_noinbounds_meta
136,184,064✔
240
    @boundscheck checkbounds(Bool, a, i) || return false
136,570,182✔
241
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
136,569,760✔
242
end
243

244

245
## copy ##
246

247
"""
248
    unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
249

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

253
The `unsafe` prefix on this function indicates that no validation is performed on the
254
pointers `dest` and `src` to ensure that they are valid. Incorrect usage may corrupt or
255
segfault your program, in the same manner as C.
256
"""
257
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
3,188✔
258
    # Do not use this to copy data between pointer arrays.
259
    # It can't be made safe no matter how carefully you checked.
260
    memmove(dest, src, n * aligned_sizeof(T))
23,040,276✔
261
    return dest
19,588,905✔
262
end
263

264
"""
265
    unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
266

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

270
The `unsafe` prefix on this function indicates that no validation is performed to ensure
271
that n is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
272
the same manner as C.
273
"""
274
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
5✔
275
    n == 0 && return dest
12,360,886✔
276
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
24,541,179✔
277
    return dest
12,270,592✔
278
end
279

280
"""
281
    copyto!(dest, doffs, src, soffs, n)
282

283
Copy `n` elements from collection `src` starting at the linear index `soffs`, to array `dest` starting at
284
the index `doffs`. Return `dest`.
285
"""
286
copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
228,906✔
287
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
387✔
288
copyto!(dest::Memory, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
153,498,017✔
289

290
# this is only needed to avoid possible ambiguities with methods added in some packages
291
copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where {T} = _copyto_impl!(dest, doffs, src, soffs, n)
70,505,849✔
292

293
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
75✔
294
    n == 0 && return dest
112,663,294✔
295
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
111,827,447✔
296
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
111,830,189✔
297
    @boundscheck checkbounds(src, soffs:soffs+n-1)
111,830,087✔
298
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
111,830,120✔
299
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
300
        unsafe_copyto!(dest, src, n)
191,671,360✔
301
    end
302
    return dest
79,841,353✔
303
end
304

305

306
# Outlining this because otherwise a catastrophic inference slowdown
307
# occurs, see discussion in #27874.
308
# It is also mitigated by using a constant string.
309
_throw_argerror(s) = (@noinline; throw(ArgumentError(s)))
12✔
310

311
_copyto2arg!(dest, src) = copyto!(dest, firstindex(dest), src, firstindex(src), length(src))
2,631,661✔
312

313
copyto!(dest::Array, src::Array) = _copyto2arg!(dest, src)
116,363✔
314
copyto!(dest::Array, src::Memory) = _copyto2arg!(dest, src)
×
315
copyto!(dest::Memory, src::Array) = _copyto2arg!(dest, src)
×
316

317
# also to avoid ambiguities in packages
318
copyto!(dest::Array{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
2,514,872✔
319
copyto!(dest::Array{T}, src::Memory{T}) where {T} = _copyto2arg!(dest, src)
387✔
320
copyto!(dest::Memory{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
39✔
321

322
# N.B: This generic definition in for multidimensional arrays is here instead of
323
# `multidimensional.jl` for bootstrapping purposes.
324
"""
325
    fill!(A, x)
326

327
Fill array `A` with the value `x`. If `x` is an object reference, all elements will refer to
328
the same object. `fill!(A, Foo())` will return `A` filled with the result of evaluating
329
`Foo()` once.
330

331
# Examples
332
```jldoctest
333
julia> A = zeros(2,3)
334
2×3 Matrix{Float64}:
335
 0.0  0.0  0.0
336
 0.0  0.0  0.0
337

338
julia> fill!(A, 2.)
339
2×3 Matrix{Float64}:
340
 2.0  2.0  2.0
341
 2.0  2.0  2.0
342

343
julia> a = [1, 1, 1]; A = fill!(Vector{Vector{Int}}(undef, 3), a); a[1] = 2; A
344
3-element Vector{Vector{Int64}}:
345
 [2, 1, 1]
346
 [2, 1, 1]
347
 [2, 1, 1]
348

349
julia> x = 0; f() = (global x += 1; x); fill!(Vector{Int}(undef, 3), f())
350
3-element Vector{Int64}:
351
 1
352
 1
353
 1
354
```
355
"""
356
function fill!(A::AbstractArray{T}, x) where T
2,951✔
357
    @inline
14,817,156✔
358
    xT = x isa T ? x : convert(T, x)::T
14,817,309✔
359
    return _fill!(A, xT)
5,800,441,756✔
360
end
361
function _fill!(A::AbstractArray{T}, x::T) where T
4,670✔
362
    for i in eachindex(A)
21,014,072✔
363
        A[i] = x
5,818,312,293✔
364
    end
6,442,450,941✔
365
    return A
14,843,405✔
366
end
367

368
"""
369
    copy(x)
370

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

375
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
376
"""
377
copy
378

379
@eval function copy(a::Array)
469,582✔
380
    # `copy` only throws when the size exceeds the max allocation size,
381
    # but since we're copying an existing array, we're guaranteed that this will not happen.
382
    @_nothrow_meta
4,833,839✔
383
    ref = a.ref
7,274,388✔
384
    newmem = typeof(ref.mem)(undef, length(a))
7,274,388✔
385
    @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a))
12,785,355✔
386
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
7,274,388✔
387
end
388

389
# a mutating version of copyto! that results in dst aliasing src afterwards
390
function _take!(dst::Array{T,N}, src::Array{T,N}) where {T,N}
391
    if getfield(dst, :ref) !== getfield(src, :ref)
900✔
392
        setfield!(dst, :ref, getfield(src, :ref))
45✔
393
    end
394
    if getfield(dst, :size) !== getfield(src, :size)
900✔
395
        setfield!(dst, :size, getfield(src, :size))
674✔
396
    end
397
    return dst
900✔
398
end
399

400
## Constructors ##
401

402
similar(a::Vector{T}) where {T}                    = Vector{T}(undef, size(a,1))
383,181✔
403
similar(a::Matrix{T}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
12,858✔
404
similar(a::Vector{T}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
43,799✔
405
similar(a::Matrix{T}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
38,639✔
406
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
56,922✔
407
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
25,488,304✔
408
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
2,598✔
409
similar(::Type{Array{T,N}}, dims::Dims) where {T,N} = similar(Array{T}, dims)
43,871,039✔
410

411
# T[x...] constructs Array{T,1}
412
"""
413
    getindex(type[, elements...])
414

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

418
# Examples
419
```jldoctest
420
julia> Int8[1, 2, 3]
421
3-element Vector{Int8}:
422
 1
423
 2
424
 3
425

426
julia> getindex(Int8, 1, 2, 3)
427
3-element Vector{Int8}:
428
 1
429
 2
430
 3
431
```
432
"""
433
function getindex(::Type{T}, vals...) where T
262,267✔
434
    @inline
13,555,187✔
435
    @_effect_free_terminates_locally_meta
13,555,187✔
436
    a = Vector{T}(undef, length(vals))
103,343,812✔
437
    if vals isa NTuple
13,555,187✔
438
        @_safeindex for i in 1:length(vals)
13,413,762✔
439
            a[i] = vals[i]
1,276,047✔
440
        end
1,177,615✔
441
    else
442
        # use afoldl to avoid type instability inside loop
443
        afoldl(1, vals...) do i, v
177,623✔
444
            @inbounds a[i] = v
373,830✔
445
            return i + 1
373,827✔
446
        end
447
    end
448
    return a
13,573,187✔
449
end
450

451
function getindex(::Type{Any}, @nospecialize vals...)
3,090,458✔
452
    @_effect_free_terminates_locally_meta
3,290,854✔
453
    a = Vector{Any}(undef, length(vals))
3,343,259✔
454
    @_safeindex for i = 1:length(vals)
5,328,855✔
455
        a[i] = vals[i]
9,202,993✔
456
    end
14,997,490✔
457
    return a
3,307,054✔
458
end
459
getindex(::Type{Any}) = Vector{Any}()
82,914,676✔
460

461
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
22✔
462
    ref = a.ref
351,626✔
463
    t = @_gc_preserve_begin ref
351,626✔
464
    p = unsafe_convert(Ptr{Cvoid}, ref)
351,626✔
465
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
351,635✔
466
    @_gc_preserve_end t
351,617✔
467
    return a
43,328✔
468
end
469

470
to_dim(d::Integer) = d
×
471
to_dim(d::OneTo) = last(d)
9,003✔
472

473
"""
474
    fill(value, dims::Tuple)
475
    fill(value, dims...)
476

477
Create an array of size `dims` with every location set to `value`.
478

479
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
480
with `1.0` in every location of the array.
481

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

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

495
```jldoctest
496
julia> v = fill([], 3)
497
3-element Vector{Vector{Any}}:
498
 []
499
 []
500
 []
501

502
julia> v[1] === v[2] === v[3]
503
true
504

505
julia> value = v[1]
506
Any[]
507

508
julia> push!(value, 867_5309)
509
1-element Vector{Any}:
510
 8675309
511

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

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

522
```jldoctest
523
julia> v2 = [[] for _ in 1:3]
524
3-element Vector{Vector{Any}}:
525
 []
526
 []
527
 []
528

529
julia> v2[1] === v2[2] === v2[3]
530
false
531

532
julia> push!(v2[1], 8675309)
533
1-element Vector{Any}:
534
 8675309
535

536
julia> v2
537
3-element Vector{Vector{Any}}:
538
 [8675309]
539
 []
540
 []
541
```
542

543
See also [`fill!`](@ref), [`zeros`](@ref), [`ones`](@ref), [`similar`](@ref).
544

545
# Examples
546
```jldoctest
547
julia> fill(1.0, (2,3))
548
2×3 Matrix{Float64}:
549
 1.0  1.0  1.0
550
 1.0  1.0  1.0
551

552
julia> fill(42)
553
0-dimensional Array{Int64, 0}:
554
42
555

556
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
557
2-element Vector{Vector{Float64}}:
558
 [0.0, 0.0]
559
 [0.0, 0.0]
560

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

563
julia> A # both A[1] and A[2] are the very same vector
564
2-element Vector{Vector{Float64}}:
565
 [42.0, 0.0]
566
 [42.0, 0.0]
567
```
568
"""
569
function fill end
570

571
fill(v, dims::DimOrInd...) = fill(v, dims)
102,750,110✔
572
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
573
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
102,750,290✔
574
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
42✔
575
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
543✔
576

577
"""
578
    zeros([T=Float64,] dims::Tuple)
579
    zeros([T=Float64,] dims...)
580

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

584
# Examples
585
```jldoctest
586
julia> zeros(1)
587
1-element Vector{Float64}:
588
 0.0
589

590
julia> zeros(Int8, 2, 3)
591
2×3 Matrix{Int8}:
592
 0  0  0
593
 0  0  0
594
```
595
"""
596
function zeros end
597

598
"""
599
    ones([T=Float64,] dims::Tuple)
600
    ones([T=Float64,] dims...)
601

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

605
# Examples
606
```jldoctest
607
julia> ones(1,2)
608
1×2 Matrix{Float64}:
609
 1.0  1.0
610

611
julia> ones(ComplexF64, 2, 3)
612
2×3 Matrix{ComplexF64}:
613
 1.0+0.0im  1.0+0.0im  1.0+0.0im
614
 1.0+0.0im  1.0+0.0im  1.0+0.0im
615
```
616
"""
617
function ones end
618

619
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
620
    @eval begin
621
        $fname(dims::DimOrInd...) = $fname(dims)
448,917✔
622
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
3,257,947,513✔
623
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
466,287✔
624
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
12,282✔
625
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
36,361✔
626
            a = Array{T,N}(undef, dims)
3,165,936✔
627
            fill!(a, $felt(T))
4,534,919,097✔
628
            return a
2,857,494✔
629
        end
630
        function $fname(::Type{T}, dims::Tuple{}) where {T}
631
            a = Array{T}(undef)
130✔
632
            fill!(a, $felt(T))
130✔
633
            return a
130✔
634
        end
635
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
636
            a = similar(Array{T,N}, dims)
4,962✔
637
            fill!(a, $felt(T))
11,124✔
638
            return a
4,962✔
639
        end
640
    end
641
end
642

643
## Conversions ##
644

645
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
303,441✔
646

647
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
552✔
648

649
## Constructors ##
650

651
# constructors should make copies
652
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
165,604✔
653
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
24,870✔
654

655
## copying iterators to containers
656

657
"""
658
    collect(element_type, collection)
659

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

663
# Examples
664
```jldoctest
665
julia> collect(Float64, 1:2:5)
666
3-element Vector{Float64}:
667
 1.0
668
 3.0
669
 5.0
670
```
671
"""
672
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
324,661✔
673

674
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
4,074✔
675
    copyto!(_array_for_inner(T, isz, _similar_shape(itr, isz)), itr)
676
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
320,546✔
677
    a = Vector{T}()
320,571✔
678
    for x in itr
638,424✔
679
        push!(a, x)
573,501✔
680
    end
829,281✔
681
    return a
320,571✔
682
end
683

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

687
_similar_shape(itr, ::SizeUnknown) = nothing
367✔
688
_similar_shape(itr, ::HasLength) = length(itr)::Integer
83,774,185✔
689
_similar_shape(itr, ::HasShape) = axes(itr)
43,704,859✔
690

691
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
298,196✔
692
    similar(c, T, 0)
693
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
352,026✔
694
    similar(c, T, len)
695
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
704,797✔
696
    similar(c, T, axs)
697

698
# make a collection appropriate for collecting `itr::Generator`
699
_array_for_inner(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
367✔
700
_array_for_inner(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
83,408,384✔
701
_array_for_inner(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
34,835,652✔
702

703
# used by syntax lowering for simple typed comprehensions
704
_array_for(::Type{T}, itr, isz) where {T} = _array_for_inner(T, isz, _similar_shape(itr, isz))
124,806,494✔
705

706

707
"""
708
    collect(iterator)
709

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

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

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

722
# Examples
723

724
Collect items from a `UnitRange{Int64}` collection:
725

726
```jldoctest
727
julia> collect(1:3)
728
3-element Vector{Int64}:
729
 1
730
 2
731
 3
732
```
733

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

736
```jldoctest
737
julia> collect(x^2 for x in 1:3)
738
3-element Vector{Int64}:
739
 1
740
 4
741
 9
742
```
743

744
Collecting an empty iterator where the result type depends on type inference:
745

746
```jldoctest
747
julia> [rand(Bool) ? 1 : missing for _ in []]
748
Union{Missing, Int64}[]
749
```
750

751
When the iterator is non-empty, the result type depends only on values:
752

753
```julia-repl
754
julia> [rand(Bool) ? 1 : missing for _ in [""]]
755
1-element Vector{Int64}:
756
 1
757
```
758
"""
759
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
1,862,478✔
760

761
collect(A::AbstractArray) = _collect_indices(axes(A), A)
424,566✔
762

763
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
927,467✔
764

765
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
303,385✔
766
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
767

768
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
297,712✔
769
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
297,874✔
770
    for x in itr
578,845✔
771
        push!(a,x)
31,411,433✔
772
    end
42,676,493✔
773
    return a
297,871✔
774
end
775

776
function _collect_indices(::Tuple{}, A)
777
    dest = Array{eltype(A),0}(undef)
77✔
778
    isempty(A) && return dest
77✔
779
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
77✔
780
end
781
function _collect_indices(indsA::Tuple{Vararg{OneTo}}, A)
14,186✔
782
    dest = Array{eltype(A)}(undef, length.(indsA))
286,137✔
783
    isempty(A) && return dest
286,140✔
784
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
286,100✔
785
end
786
function _collect_indices(indsA, A)
106✔
787
    B = Array{eltype(A)}(undef, length.(indsA))
359✔
788
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
359✔
789
end
790

791
# NOTE: this function is not meant to be called, only inferred, for the
792
# purpose of bounding the types of values generated by an iterator.
793
function _iterator_upper_bound(itr)
×
794
    x = iterate(itr)
×
795
    while x !== nothing
×
796
        val = getfield(x, 1)
×
797
        if inferencebarrier(nothing)
×
798
            return val
×
799
        end
800
        x = iterate(itr, getfield(x, 2))
×
801
    end
×
802
    throw(nothing)
×
803
end
804

805
# define this as a macro so that the call to Core.Compiler
806
# gets inlined into the caller before recursion detection
807
# gets a chance to see it, so that recursive calls to the caller
808
# don't trigger the inference limiter
809
macro default_eltype(itr)
810
    I = esc(itr)
811
    return quote
812
        if $I isa Generator && ($I).f isa Type
3,223,098✔
813
            T = ($I).f
41,546✔
814
        else
815
            T = Base._return_type(_iterator_upper_bound, Tuple{typeof($I)})
3,181,552✔
816
        end
817
        promote_typejoin_union(T)
3,223,259✔
818
    end
819
end
820

821
function collect(itr::Generator)
865,888✔
822
    isz = IteratorSize(itr.iter)
2,131,112✔
823
    et = @default_eltype(itr)
824
    if isa(isz, SizeUnknown)
2,131,112✔
825
        return grow_to!(Vector{et}(), itr)
565,669✔
826
    else
827
        shp = _similar_shape(itr, isz)
1,640,978✔
828
        y = iterate(itr)
3,095,382✔
829
        if y === nothing
1,565,726✔
830
            return _array_for_inner(et, isz, shp)
3,883✔
831
        end
832
        v1, st = y
1,561,837✔
833
        dest = _array_for_inner(typeof(v1), isz, shp)
1,562,433✔
834
        # The typeassert gives inference a helping hand on the element type and dimensionality
835
        # (work-around for #28382)
836
        et′ = et <: Type ? Type : et
1,561,837✔
837
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
1,562,415✔
838
        collect_to_with_first!(dest, v1, itr, st)::RT
31,541,137✔
839
    end
840
end
841

842
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
322✔
843
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
844

845
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
418,411✔
846
    et = @default_eltype(itr)
519,893✔
847
    shp = _similar_shape(itr, isz)
700,990✔
848
    y = iterate(itr)
1,382,822✔
849
    if y === nothing
700,975✔
850
        return _similar_for(c, et, itr, isz, shp)
18,838✔
851
    end
852
    v1, st = y
501,052✔
853
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
682,338✔
854
    # The typeassert gives inference a helping hand on the element type and dimensionality
855
    # (work-around for #28382)
856
    et′ = et <: Type ? Type : et
501,052✔
857
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
501,220✔
858
    collect_to_with_first!(dest, v1, itr, st)::RT
682,137✔
859
end
860

861
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
324,388✔
862
    i1 = first(LinearIndices(dest))
2,062,901✔
863
    dest[i1] = v1
2,242,536✔
864
    return collect_to!(dest, itr, i1+1, st)
33,112,743✔
865
end
866

867
function collect_to_with_first!(dest, v1, itr, st)
×
868
    push!(dest, v1)
×
869
    return grow_to!(dest, itr, st)
×
870
end
871

872
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
18,869✔
873
    @inline
19,571✔
874
    new = similar(dest, promote_typejoin(T, typeof(el)))
19,571✔
875
    f = first(LinearIndices(dest))
19,571✔
876
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
39,117✔
877
    @inbounds new[i] = el
19,571✔
878
    return new
19,571✔
879
end
880

881
# Batch-widen an array given (index => value) pairs that don't fit the current element type.
882
function setindices_widen_up_to(dest::AbstractArray, widen_buffers::Vector{Vector{Pair{Int, Any}}})
285✔
883
    widen_pairs = reduce(vcat, widen_buffers; init=Pair{Int,Any}[])
570✔
884
    isempty(widen_pairs) && return dest
285✔
885
    new_T = eltype(dest)
75✔
886
    for p in widen_pairs
75✔
887
        new_T = promote_typejoin(new_T, typeof(p.second))
105✔
888
    end
105✔
889
    new_T === eltype(dest) && return dest
75✔
890
    # Function barrier: specializes on new_T so the compiler sees
891
    # concrete element types for both source and destination arrays.
892
    return _setindices_widen_up_to(new_T, dest, widen_pairs)
75✔
893
end
894

895
function _setindices_widen_up_to(::Type{T}, dest::AbstractArray, widen_pairs::Vector{Pair{Int, Any}}) where T
75✔
896
    new = similar(dest, T)
75✔
897
    copyto!(new, dest)
150✔
898
    for (idx, val) in widen_pairs
75✔
899
        @inbounds new[idx] = val
105✔
900
    end
105✔
901
    return new
75✔
902
end
903

904
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
370,928✔
905
    # collect to dest array, checking the type of each result. if a result does not
906
    # match, widen the result type and re-dispatch.
907
    i = offs
2,082,472✔
908
    while true
349,050,100✔
909
        y = iterate(itr, st)
695,843,917✔
910
        y === nothing && break
349,050,066✔
911
        el, st = y
345,916,651✔
912
        if el isa T
345,916,651✔
913
            @inbounds dest[i] = el
346,787,993✔
914
            i += 1
346,787,993✔
915
        else
916
            new = setindex_widen_up_to(dest, el, i)
19,571✔
917
            return collect_to!(new, itr, i+1, st)
19,571✔
918
        end
919
    end
346,787,993✔
920
    return dest
2,242,502✔
921
end
922

923
function grow_to!(dest, itr)
7,804✔
924
    y = iterate(itr)
568,442✔
925
    y === nothing && return dest
565,769✔
926
    dest2 = empty(dest, typeof(y[1]))
3,828✔
927
    push!(dest2, y[1])
4,219✔
928
    grow_to!(dest2, itr, y[2])
3,760✔
929
end
930

931
function push_widen(dest, el)
173✔
932
    @inline
226✔
933
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
228✔
934
    if new isa AbstractSet
226✔
935
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
936
        union!(new, dest)
2✔
937
    else
938
        append!(new, dest)
448✔
939
    end
940
    push!(new, el)
226✔
941
    return new
226✔
942
end
943

944
function grow_to!(dest, itr, st)
3,938✔
945
    T = eltype(dest)
3,985✔
946
    y = iterate(itr, st)
6,958✔
947
    while y !== nothing
23,392✔
948
        el, st = y
19,633✔
949
        if el isa T
19,633✔
950
            push!(dest, el)
20,540✔
951
        else
952
            new = push_widen(dest, el)
279✔
953
            return grow_to!(new, itr, st)
226✔
954
        end
955
        y = iterate(itr, st)
28,911✔
956
    end
19,407✔
957
    return dest
3,759✔
958
end
959

960
## Indexing: getindex ##
961

962
"""
963
    getindex(collection, key...)
964

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

968
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
969

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

977
julia> getindex(A, "a")
978
1
979
```
980
"""
981
function getindex end
982

983
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
168,928✔
984
    @inline
347,013,312✔
985
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
469,209,050✔
986
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
469,214,375✔
987
end
988

989
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
990
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
209,468✔
991
    @inline
2,420,089✔
992
    @boundscheck checkbounds(A, I)
24,493,567✔
993
    lI = length(I)
24,493,563✔
994
    X = similar(A, axes(I))
24,493,596✔
995
    if lI > 0
24,493,563✔
996
        copyto!(X, firstindex(X), A, first(I), lI)
47,556,586✔
997
    end
998
    return X
24,480,113✔
999
end
1000

1001
# getindex for carrying out logical indexing for AbstractUnitRange{Bool} as Bool <: Integer
1002
getindex(a::Array, r::AbstractUnitRange{Bool}) = getindex(a, to_index(r))
63✔
1003

1004
function getindex(A::Array, c::Colon)
13,366✔
1005
    lI = length(A)
49,249✔
1006
    X = similar(A, lI)
49,249✔
1007
    if lI > 0
49,249✔
1008
        unsafe_copyto!(X, 1, A, 1, lI)
98,486✔
1009
    end
1010
    return X
49,249✔
1011
end
1012

1013
# This is redundant with the abstract fallbacks, but needed for bootstrap
1014
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
9,511,664✔
1015
    return S[ A[i] for i in I ]
9,512,384✔
1016
end
1017

1018
## Indexing: setindex! ##
1019

1020
"""
1021
    setindex!(collection, value, key...)
1022

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

1026
# Examples
1027
```jldoctest; filter = r"^\\s+\\S+\\s+=>\\s+\\d\$"m
1028
julia> a = Dict("a"=>1)
1029
Dict{String, Int64} with 1 entry:
1030
  "a" => 1
1031

1032
julia> setindex!(a, 2, "b")
1033
Dict{String, Int64} with 2 entries:
1034
  "b" => 2
1035
  "a" => 1
1036
```
1037
"""
1038
function setindex! end
1039

1040
function setindex!(A::Array{T}, x, i::Int) where {T}
17,440,225✔
1041
    @_propagate_inbounds_meta
5,409,681,755✔
1042
    x = x isa T ? x : convert(T, x)::T
5,414,237,187✔
1043
    return _setindex!(A, x, i)
6,442,450,941✔
1044
end
1045
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
1,067✔
1046
    @_noub_if_noinbounds_meta
5,403,941,778✔
1047
    @boundscheck checkbounds(A, i)
6,442,450,941✔
1048
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
6,442,450,941✔
1049
    return A
5,968,923,118✔
1050
end
1051
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
2,536,714✔
1052
    @_propagate_inbounds_meta
144,238,479✔
1053
    x = x isa T ? x : convert(T, x)::T
144,250,086✔
1054
    return _setindex!(A, x, i1, i2, I...)
192,004,600✔
1055
end
1056
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
12✔
1057
    @inline
141,063,959✔
1058
    @_noub_if_noinbounds_meta
141,063,959✔
1059
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
192,019,156✔
1060
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
192,019,102✔
1061
    return A
189,117,497✔
1062
end
1063

1064
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
272,515,829✔
1065
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
290,090,921✔
1066
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
208,058,790✔
1067
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
583,197,761✔
1068
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
1069
    __safe_setindex!(A, convert(T, x)::T, i))
109,186✔
1070

1071
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1072
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
368✔
1073
    @_propagate_inbounds_meta
2,466,232✔
1074
    @boundscheck setindex_shape_check(X, length(I))
2,520,108✔
1075
    @boundscheck checkbounds(A, I)
2,520,108✔
1076
    require_one_based_indexing(X)
2,466,232✔
1077
    X′ = unalias(A, X)
2,467,699✔
1078
    I′ = unalias(A, I)
2,466,235✔
1079
    count = 1
2,466,232✔
1080
    for i in I′
2,596,717✔
1081
        @inbounds A[i] = X′[count]
17,927,403✔
1082
        count += 1
17,927,403✔
1083
    end
33,475,020✔
1084
    return A
2,508,135✔
1085
end
1086

1087
# Faster contiguous setindex! with copyto!
1088
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
358✔
1089
    @inline
3,039,521✔
1090
    @boundscheck checkbounds(A, I)
3,040,642✔
1091
    lI = length(I)
3,040,642✔
1092
    @boundscheck setindex_shape_check(X, lI)
3,040,642✔
1093
    if lI > 0
3,040,642✔
1094
        unsafe_copyto!(A, first(I), X, 1, lI)
6,079,320✔
1095
    end
1096
    return A
3,040,550✔
1097
end
1098
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
132✔
1099
    @inline
222✔
1100
    lI = length(A)
222✔
1101
    @boundscheck setindex_shape_check(X, lI)
222✔
1102
    if lI > 0
222✔
1103
        unsafe_copyto!(A, 1, X, 1, lI)
444✔
1104
    end
1105
    return A
222✔
1106
end
1107

1108
# Pick new memory size for efficiently growing an array
1109
# TODO: This should know about the size of our GC pools
1110
# Specifically we are wasting ~10% of memory for small arrays
1111
# by not picking memory sizes that max out a GC pool
1112
function overallocation(maxsize)
445✔
1113
    # compute maxsize = maxsize + 3*maxsize^(7/8) + maxsize/8
1114
    # for small n, we grow faster than O(n)
1115
    # for large n, we grow at O(n/8)
1116
    # and as we reach O(memory) for memory>>1MB,
1117
    # this means we end by adding about 10% of memory each time
1118
    # most commonly, this will take steps of 0-3-9-34 or 1-4-16-66 or 2-8-33
1119
    exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
22,492,691✔
1120
    maxsize += (1 << div(exp2 * 7, 8)) * 3 + div(maxsize, 8)
22,492,691✔
1121
    return maxsize
22,003,024✔
1122
end
1123

1124
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
22,304,992✔
1125

1126
function _growbeg_internal!(a::Vector, delta::Int, len::Int)
745,721✔
1127
    @_terminates_locally_meta
745,721✔
1128
    ref = a.ref
745,721✔
1129
    mem = ref.mem
745,721✔
1130
    offset = memoryrefoffset(ref)
745,721✔
1131
    newlen = len + delta
745,721✔
1132
    memlen = length(mem)
745,721✔
1133
    if offset + len - 1 > memlen || offset < 1
1,491,442✔
1134
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1135
    end
1136
    # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1137
    # the +1 is because I didn't want to have an off by 1 error.
1138
    newmemlen = max(overallocation(len), len + 2 * delta + 1)
745,721✔
1139
    newoffset = div(newmemlen - newlen, 2) + 1
745,721✔
1140
    # If there is extra data after the end of the array we can use that space so long as there is enough
1141
    # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1142
    # Specifically, we want to ensure that we will only do this operation once before
1143
    # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1144
    if newoffset + newlen < memlen
745,721✔
1145
        newoffset = div(memlen - newlen, 2) + 1
8,296✔
1146
        newmem = mem
8,296✔
1147
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
12,679✔
1148
        for j in offset:newoffset+delta-1
10,753✔
1149
            @inbounds _unsetindex!(mem, j)
138,176✔
1150
        end
240,996✔
1151
    else
1152
        newmem = array_new_memory(mem, newmemlen)
737,425✔
1153
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
737,425✔
1154
    end
1155
    if ref !== a.ref
745,721✔
1156
        throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1157
    end
1158
    setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
745,721✔
1159
end
1160

1161
function _growbeg!(a::Vector, delta::Integer)
57✔
1162
    @_noub_meta
16,328,373✔
1163
    delta = Int(delta)
16,328,373✔
1164
    delta == 0 && return # avoid attempting to index off the end
16,349,907✔
1165
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
16,348,963✔
1166
    ref = a.ref
27,402,109✔
1167
    len = length(a)
27,402,109✔
1168
    offset = memoryrefoffset(ref)
27,402,109✔
1169
    newlen = len + delta
27,402,109✔
1170
    # if offset is far enough advanced to fit data in existing memory without copying
1171
    if delta <= offset - 1
27,402,109✔
1172
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
21,109,941✔
1173
        setfield!(a, :size, (newlen,))
21,109,941✔
1174
    else
1175
        @noinline _growbeg_internal!(a, delta, len)
6,292,168✔
1176
        setfield!(a, :size, (newlen,))
6,292,168✔
1177
    end
1178
    return
27,402,095✔
1179
end
1180

1181
function _growend_internal!(a::Vector, delta::Int, len::Int)
21,488,335✔
1182
    ref = a.ref
21,488,335✔
1183
    mem = ref.mem
21,488,335✔
1184
    memlen = length(mem)
21,488,335✔
1185
    newlen = len + delta
21,488,335✔
1186
    offset = memoryrefoffset(ref)
21,488,335✔
1187
    newmemlen = offset + newlen - 1
21,488,335✔
1188
    if offset + len - 1 > memlen || offset < 1
42,976,670✔
1189
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1190
    end
1191

1192
    if offset - 1 > div(5 * newlen, 4)
21,488,335✔
1193
        # If the offset is far enough that we can copy without resizing
1194
        # while maintaining proportional spacing on both ends of the array
1195
        # note that this branch prevents infinite growth when doing combinations
1196
        # of push! and popfirst! (i.e. when using a Vector as a queue)
1197
        newmem = mem
1,770,627✔
1198
        newoffset = div(newlen, 8) + 1
1,770,627✔
1199
    else
1200
        # grow either by our computed overallocation factor
1201
        # or exactly the requested size, whichever is larger
1202
        # TODO we should possibly increase the offset if the current offset is nonzero.
1203
        newmemlen2 = max(overallocation(memlen), newmemlen)
19,717,708✔
1204
        newmem = array_new_memory(mem, newmemlen2)
19,721,301✔
1205
        newoffset = offset
19,717,708✔
1206
    end
1207
    newref = @inbounds memoryref(newmem, newoffset)
21,488,335✔
1208
    unsafe_copyto!(newref, ref, len)
28,673,834✔
1209
    if ref !== a.ref
21,488,335✔
1210
        @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1211
    end
1212
    setfield!(a, :ref, newref)
21,488,335✔
1213
return
21,488,335✔
1214
end
1215

1216
function _growend!(a::Vector, delta::Integer)
643✔
1217
    @_noub_meta
486,609,551✔
1218
    delta = Int(delta)
486,609,551✔
1219
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
496,889,516✔
1220
    ref = a.ref
674,931,057✔
1221
    mem = ref.mem
674,931,057✔
1222
    memlen = length(mem)
674,931,057✔
1223
    len = length(a)
674,931,057✔
1224
    newlen = len + delta
674,931,057✔
1225
    offset = memoryrefoffset(ref)
674,931,057✔
1226
    newmemlen = offset + newlen - 1
674,931,057✔
1227
    if memlen < newmemlen
674,931,057✔
1228
        @noinline _growend_internal!(a, delta, len)
44,665,882✔
1229
    end
1230
    setfield!(a, :size, (newlen,))
674,931,057✔
1231
    return
674,780,945✔
1232
end
1233

1234
function _growat!(a::Vector, i::Integer, delta::Integer)
1,565,604✔
1235
    @_terminates_globally_noub_meta
1,565,607✔
1236
    delta = Int(delta)
1,565,607✔
1237
    i = Int(i)
1,565,607✔
1238
    i == 1 && return _growbeg!(a, delta)
1,565,607✔
1239
    len = length(a)
1,009,513✔
1240
    i == len + 1 && return _growend!(a, delta)
1,009,513✔
1241
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
902,201✔
1242
    1 < i <= len || throw(BoundsError(a, i))
902,201✔
1243
    ref = a.ref
902,201✔
1244
    mem = ref.mem
902,201✔
1245
    memlen = length(mem)
902,201✔
1246
    newlen = len + delta
902,201✔
1247
    offset = memoryrefoffset(ref)
902,201✔
1248
    newmemlen = offset + newlen - 1
902,201✔
1249

1250
    # which side would we rather grow into?
1251
    prefer_start = i <= div(len, 2)
902,201✔
1252
    # if offset is far enough advanced to fit data in beginning of the memory
1253
    if prefer_start && delta <= offset - 1
902,201✔
1254
        newref = @inbounds memoryref(mem, offset - delta)
289,506✔
1255
        unsafe_copyto!(newref, ref, i)
579,012✔
1256
        setfield!(a, :ref, newref)
289,506✔
1257
        setfield!(a, :size, (newlen,))
289,506✔
1258
        for j in i:i+delta-1
472,199✔
1259
            @inbounds _unsetindex!(a, j)
382,441✔
1260
        end
362,076✔
1261
    elseif !prefer_start && memlen >= newmemlen
612,695✔
1262
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
834,296✔
1263
        setfield!(a, :size, (newlen,))
417,148✔
1264
        for j in i:i+delta-1
617,448✔
1265
            @inbounds _unsetindex!(a, j)
518,747✔
1266
        end
491,439✔
1267
    else
1268
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1269
        # the +1 is because I didn't want to have an off by 1 error.
1270
        newmemlen = max(overallocation(memlen), len+2*delta+1)
195,547✔
1271
        newoffset = (newmemlen - newlen) ÷ 2 + 1
195,547✔
1272
        newmem = array_new_memory(mem, newmemlen)
195,547✔
1273
        newref = @inbounds memoryref(newmem, newoffset)
195,547✔
1274
        unsafe_copyto!(newref, ref, i-1)
391,094✔
1275
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
391,094✔
1276
        setfield!(a, :ref, newref)
195,547✔
1277
        setfield!(a, :size, (newlen,))
195,547✔
1278
    end
1279
end
1280

1281
# efficiently delete part of an array
1282
function _deletebeg!(a::Vector, delta::Integer)
214,147✔
1283
    delta = Int(delta)
65,133,539✔
1284
    len = length(a)
65,902,393✔
1285
    # See comment in _deleteend!
1286
    if unsigned(delta) > unsigned(len)
65,902,393✔
1287
        throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
×
1288
    end
1289
    for i in 1:delta
65,367,341✔
1290
        @inbounds _unsetindex!(a, i)
120,066,009✔
1291
    end
172,731,357✔
1292
    newlen = len - delta
65,902,393✔
1293
    setfield!(a, :size, (newlen,))
65,902,393✔
1294
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
65,902,393✔
1295
        newref = @inbounds memoryref(a.ref, delta + 1)
46,266,906✔
1296
        setfield!(a, :ref, newref)
46,266,906✔
1297
    end
1298
    return
65,902,393✔
1299
end
1300
function _deleteend!(a::Vector, delta::Integer)
464,009✔
1301
    delta = Int(delta)
22,833,079✔
1302
    len = length(a)
48,574,915✔
1303
    # Do the comparison unsigned, to so the compiler knows `len` cannot be negative.
1304
    # This works because if delta is negative, it will overflow and still trigger.
1305
    # This enables the compiler to skip the check sometimes.
1306
    if unsigned(delta) > unsigned(len)
48,574,915✔
1307
        throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
×
1308
    end
1309
    newlen = len - delta
48,574,915✔
1310
    for i in newlen+1:len
66,124,967✔
1311
        @inbounds _unsetindex!(a, i)
115,658,934✔
1312
    end
183,955,525✔
1313
    setfield!(a, :size, (newlen,))
48,574,915✔
1314
    return
48,573,835✔
1315
end
1316
function _deleteat!(a::Vector, i::Integer, delta::Integer)
484,594✔
1317
    i = Int(i)
484,594✔
1318
    len = length(a)
484,594✔
1319
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
484,594✔
1320
    1 <= i <= len || throw(BoundsError(a, i))
484,594✔
1321
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
484,594✔
1322
    newa = a
484,594✔
1323
    if 2*i + delta <= len
484,594✔
1324
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
327,770✔
1325
        _deletebeg!(a, delta)
22,447,709✔
1326
    else
1327
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
552,846✔
1328
        _deleteend!(a, delta)
315,865✔
1329
    end
1330
    return
484,594✔
1331
end
1332
## Dequeue functionality ##
1333

1334
"""
1335
    push!(collection, items...) -> collection
1336

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

1340
# Examples
1341
```jldoctest
1342
julia> push!([1, 2, 3], 4, 5, 6)
1343
6-element Vector{Int64}:
1344
 1
1345
 2
1346
 3
1347
 4
1348
 5
1349
 6
1350
```
1351

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

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

1358
See also [`pushfirst!`](@ref).
1359
"""
1360
function push! end
1361

1362
function push!(a::Vector{T}, item) where T
83,998✔
1363
    @inline
207,230,279✔
1364
    # convert first so we don't grow the array if the assignment won't work
1365
    # and also to avoid a dynamic dynamic dispatch in the common case that
1366
    # `item` is poorly-typed and `a` is well-typed
1367
    item = item isa T ? item : convert(T, item)::T
210,691,920✔
1368
    return _push!(a, item)
381,889,181✔
1369
end
1370
function _push!(a::Vector{T}, item::T) where T
555✔
1371
    _growend!(a, 1)
381,889,175✔
1372
    @_safeindex a[length(a)] = item
381,889,175✔
1373
    return a
381,821,368✔
1374
end
1375

1376
# specialize and optimize the single argument case
1377
function push!(a::Vector{Any}, @nospecialize x)
2,006✔
1378
    _growend!(a, 1)
269,359,957✔
1379
    @_safeindex a[length(a)] = x
269,359,957✔
1380
    return a
269,359,927✔
1381
end
1382
function push!(a::Vector{Any}, @nospecialize x...)
51✔
1383
    @_terminates_locally_meta
442✔
1384
    na = length(a)
4,042✔
1385
    nx = length(x)
442✔
1386
    _growend!(a, nx)
4,042✔
1387
    @_safeindex for i = 1:nx
11,242✔
1388
        a[na+i] = x[i]
12,029✔
1389
    end
20,016✔
1390
    return a
4,042✔
1391
end
1392

1393
"""
1394
    append!(collection, collections...) -> collection.
1395

1396
For an ordered container `collection`, add the elements of each `collections`
1397
to the end of it.
1398

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

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

1410
julia> append!([1, 2, 3], [4, 5], [6])
1411
6-element Vector{Int64}:
1412
 1
1413
 2
1414
 3
1415
 4
1416
 5
1417
 6
1418
```
1419

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

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

1426
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1427
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1428
"""
1429
function append! end
1430

1431
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
30,576✔
1432
    items isa Tuple && (items = map(x -> convert(T, x), items))
9,150,772✔
1433
    n = Int(length(items))::Int
13,150,437✔
1434
    _growend!(a, n)
14,183,675✔
1435
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
23,853,292✔
1436
    return a
14,183,672✔
1437
end
1438

1439
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
524,611✔
1440
push!(a::AbstractVector, iter...) = append!(a, iter)
3,260,429✔
1441
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
57✔
1442

1443
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
313,941✔
1444
    n = Int(length(iter))::Int
314,529✔
1445
    sizehint!(a, length(a) + n; shrink=false)
313,980✔
1446
    for item in iter
403,126✔
1447
        push!(a, item)
182,097✔
1448
    end
226,731✔
1449
    a
313,929✔
1450
end
1451
function _append!(a::AbstractVector, ::IteratorSize, iter)
210,586✔
1452
    for item in iter
287,840✔
1453
        push!(a, item)
150,055✔
1454
    end
156,957✔
1455
    a
210,589✔
1456
end
1457

1458
"""
1459
    prepend!(a::Vector, collections...) -> collection
1460

1461
Insert the elements of each `collections` to the beginning of `a`.
1462

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

1466
!!! compat "Julia 1.6"
1467
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1468

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

1477
julia> prepend!([6], [1, 2], [3, 4, 5])
1478
6-element Vector{Int64}:
1479
 1
1480
 2
1481
 3
1482
 4
1483
 5
1484
 6
1485
```
1486
"""
1487
function prepend! end
1488

1489
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
6,479✔
1490
    items isa Tuple && (items = map(x -> convert(T, x), items))
1,568✔
1491
    n = length(items)
7,793✔
1492
    _growbeg!(a, n)
14,639✔
1493
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1494
    # just the last n elements instead of all of them from the first
1495
    copyto!(a, 1, items, lastindex(items)-n+1, n)
14,621✔
1496
    return a
7,793✔
1497
end
1498

1499
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
693✔
1500
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
48✔
1501
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
21✔
1502

1503
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
633✔
1504
    @_terminates_locally_meta
636✔
1505
    require_one_based_indexing(a)
636✔
1506
    n = Int(length(iter))::Int
636✔
1507
    sizehint!(a, length(a) + n; first=true, shrink=false)
636✔
1508
    n = 0
636✔
1509
    for item in iter
639✔
1510
        n += 1
1,119✔
1511
        pushfirst!(a, item)
1,122✔
1512
    end
1,107✔
1513
    reverse!(a, 1, n)
618✔
1514
    a
618✔
1515
end
1516
function _prepend!(a::Vector, ::IteratorSize, iter)
9✔
1517
    n = 0
9✔
1518
    for item in iter
15✔
1519
        n += 1
24✔
1520
        pushfirst!(a, item)
33✔
1521
    end
39✔
1522
    reverse!(a, 1, n)
6✔
1523
    a
6✔
1524
end
1525

1526
"""
1527
    resize!(a::Vector, n::Integer) -> a
1528

1529
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1530
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1531
guaranteed to be initialized.
1532

1533
# Examples
1534
```jldoctest
1535
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1536
3-element Vector{Int64}:
1537
 6
1538
 5
1539
 4
1540

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

1543
julia> length(a)
1544
8
1545

1546
julia> a[1:6]
1547
6-element Vector{Int64}:
1548
 6
1549
 5
1550
 4
1551
 3
1552
 2
1553
 1
1554
```
1555
"""
1556
function resize!(a::Vector, nl_::Integer)
1,363,347✔
1557
    nl = Int(nl_)::Int
22,977,159✔
1558
    l = length(a)
22,977,145✔
1559
    if nl > l
22,977,145✔
1560
        # Since l is positive, if nl > l, both are positive, and so nl-l is also
1561
        # positive. But the compiler does not know that, so we mask out top bit.
1562
        # This allows the compiler to skip the check
1563
        _growend!(a, (nl-l) & typemax(Int))
6,766,674✔
1564
    elseif nl != l
16,210,471✔
1565
        if nl < 0
3,425,214✔
1566
            _throw_argerror("new length must be ≥ 0")
×
1567
        end
1568
        _deleteend!(a, l-nl)
3,425,214✔
1569
    end
1570
    return a
22,977,145✔
1571
end
1572

1573
"""
1574
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1575

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

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

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

1589
See also [`resize!`](@ref).
1590

1591
# Notes on the performance model
1592

1593
For types that support `sizehint!`,
1594

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

1599
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1600
   `Base`.
1601

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

1604
!!! compat "Julia 1.11"
1605
    The `shrink` and `first` arguments were added in Julia 1.11.
1606
"""
1607
function sizehint! end
1608

1609
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
12,467,399✔
1610
    len = length(a)
2,107,524✔
1611
    ref = a.ref
2,107,524✔
1612
    mem = ref.mem
2,107,524✔
1613
    memlen = length(mem)
2,107,524✔
1614
    sz = max(Int(sz), len)
2,107,524✔
1615
    inc = sz - len
2,107,524✔
1616
    if sz <= memlen
2,107,524✔
1617
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1618
        if !shrink || memlen - sz <= div(memlen, 8)
3,617,858✔
1619
            return a
292,999✔
1620
        end
1621
        newmem = array_new_memory(mem, sz)
1,665,345✔
1622
        if first
1,661,635✔
1623
            newref = memoryref(newmem, inc + 1)
×
1624
        else
1625
            newref = memoryref(newmem)
1,661,635✔
1626
        end
1627
        unsafe_copyto!(newref, ref, len)
1,668,981✔
1628
        setfield!(a, :ref, newref)
1,661,635✔
1629
    elseif first
152,890✔
1630
        _growbeg!(a, inc)
×
1631
        newref = getfield(a, :ref)
×
1632
        newref = memoryref(newref, inc + 1)
×
1633
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
×
1634
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
×
1635
    else # last
1636
        _growend!(a, inc)
152,890✔
1637
        setfield!(a, :size, (len,)) # undo the size change from _growend!
152,890✔
1638
    end
1639
    a
1,814,525✔
1640
end
1641

1642
# Fall-back implementation for non-shrinkable collections
1643
# avoid defining this the normal way to avoid avoid infinite recursion
1644
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
4✔
1645
    get(kwargs, :first, false)::Bool
36,890✔
1646
    get(kwargs, :shrink, true)::Bool
36,890✔
1647
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
36,890✔
1648
    sizehint!(a, sz)
36,890✔
1649
end
1650

1651
"""
1652
    pop!(collection) -> item
1653

1654
Remove an item in `collection` and return it. If `collection` is an
1655
ordered container, the last item is returned; for unordered containers,
1656
an arbitrary element is returned.
1657

1658
See also [`popfirst!`](@ref), [`popat!`](@ref), [`delete!`](@ref), [`deleteat!`](@ref), [`splice!`](@ref), [`push!`](@ref).
1659

1660
# Examples
1661
```jldoctest
1662
julia> A=[1, 2, 3]
1663
3-element Vector{Int64}:
1664
 1
1665
 2
1666
 3
1667

1668
julia> pop!(A)
1669
3
1670

1671
julia> A
1672
2-element Vector{Int64}:
1673
 1
1674
 2
1675

1676
julia> S = Set([1, 2])
1677
Set{Int64} with 2 elements:
1678
  2
1679
  1
1680

1681
julia> pop!(S)
1682
2
1683

1684
julia> S
1685
Set{Int64} with 1 element:
1686
  1
1687

1688
julia> pop!(Dict(1=>2))
1689
1 => 2
1690
```
1691
"""
1692
function pop!(a::Vector)
200,451✔
1693
    if isempty(a)
39,105,920✔
1694
        _throw_argerror("array must be non-empty")
×
1695
    end
1696
    item = a[end]
39,105,920✔
1697
    _deleteend!(a, 1)
39,105,920✔
1698
    return item
39,104,840✔
1699
end
1700

1701
"""
1702
    popat!(a::Vector, i::Integer, [default])
1703

1704
Remove the item at the given `i` and return it. Subsequent items
1705
are shifted to fill the resulting gap.
1706
When `i` is not a valid index for `a`, return `default`, or throw an error if
1707
`default` is not specified.
1708

1709
See also [`pop!`](@ref), [`popfirst!`](@ref), [`deleteat!`](@ref), [`splice!`](@ref).
1710

1711
!!! compat "Julia 1.5"
1712
    This function is available as of Julia 1.5.
1713

1714
# Examples
1715
```jldoctest
1716
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1717
3
1718

1719
julia> a
1720
3-element Vector{Int64}:
1721
 4
1722
 2
1723
 1
1724

1725
julia> popat!(a, 4, missing)
1726
missing
1727

1728
julia> popat!(a, 4)
1729
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1730
[...]
1731
```
1732
"""
1733
function popat!(a::Vector, i::Integer)
12✔
1734
    @_propagate_inbounds_meta
81✔
1735
    x = a[i]
102✔
1736
    _deleteat!(a, i, 1)
84✔
1737
    x
78✔
1738
end
1739

1740
function popat!(a::Vector, i::Integer, default)
6✔
1741
    if 1 <= i <= length(a)
6✔
1742
        x = @inbounds a[i]
3✔
1743
        _deleteat!(a, i, 1)
3✔
1744
        x
3✔
1745
    else
1746
        default
3✔
1747
    end
1748
end
1749

1750
"""
1751
    pushfirst!(collection, items...) -> collection
1752

1753
Insert one or more `items` at the beginning of `collection`.
1754

1755
This function is called `unshift` in many other programming languages.
1756

1757
# Examples
1758
```jldoctest
1759
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1760
6-element Vector{Int64}:
1761
 5
1762
 6
1763
 1
1764
 2
1765
 3
1766
 4
1767
```
1768
"""
1769
function pushfirst!(a::Vector{T}, item) where T
1,011✔
1770
    @inline
15,084,252✔
1771
    item = item isa T ? item : convert(T, item)::T
15,084,261✔
1772
    return _pushfirst!(a, item)
15,384,867✔
1773
end
1774
function _pushfirst!(a::Vector{T}, item::T) where T
1775
    _growbeg!(a, 1)
15,385,800✔
1776
    @_safeindex a[1] = item
15,307,801✔
1777
    return a
15,307,801✔
1778
end
1779

1780
# specialize and optimize the single argument case
1781
function pushfirst!(a::Vector{Any}, @nospecialize x)
320✔
1782
    _growbeg!(a, 1)
17,199,043✔
1783
    @_safeindex a[1] = x
11,530,394✔
1784
    return a
11,530,394✔
1785
end
1786
function pushfirst!(a::Vector{Any}, @nospecialize x...)
6✔
1787
    @_terminates_locally_meta
6✔
1788
    nx = length(x)
6✔
1789
    _growbeg!(a, nx)
12✔
1790
    @_safeindex for i = 1:nx
6✔
1791
        a[i] = x[i]
18✔
1792
    end
30✔
1793
    return a
6✔
1794
end
1795

1796
"""
1797
    popfirst!(collection) -> item
1798

1799
Remove the first `item` from `collection`.
1800

1801
This function is called `shift` in many other programming languages.
1802

1803
See also [`pop!`](@ref), [`popat!`](@ref), [`delete!`](@ref).
1804

1805
# Examples
1806
```jldoctest
1807
julia> A = [1, 2, 3, 4, 5, 6]
1808
6-element Vector{Int64}:
1809
 1
1810
 2
1811
 3
1812
 4
1813
 5
1814
 6
1815

1816
julia> popfirst!(A)
1817
1
1818

1819
julia> A
1820
5-element Vector{Int64}:
1821
 2
1822
 3
1823
 4
1824
 5
1825
 6
1826
```
1827
"""
1828
function popfirst!(a::Vector)
1,752✔
1829
    if isempty(a)
65,455,811✔
1830
        _throw_argerror("array must be non-empty")
×
1831
    end
1832
    item = a[1]
65,455,811✔
1833
    _deletebeg!(a, 1)
65,455,811✔
1834
    return item
65,455,811✔
1835
end
1836

1837
"""
1838
    insert!(a::Vector, index::Integer, item)
1839

1840
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1841
the resulting `a`.
1842

1843
See also [`push!`](@ref), [`replace`](@ref), [`popat!`](@ref), [`splice!`](@ref).
1844

1845
# Examples
1846
```jldoctest
1847
julia> insert!(Any[1:6;], 3, "here")
1848
7-element Vector{Any}:
1849
 1
1850
 2
1851
  "here"
1852
 3
1853
 4
1854
 5
1855
 6
1856
```
1857
"""
1858
function insert!(a::Vector{T}, i::Integer, item) where T
971✔
1859
    @_propagate_inbounds_meta
1,940,360✔
1860
    item = item isa T ? item : convert(T, item)::T
1,940,374✔
1861
    return _insert!(a, i, item)
2,595,109✔
1862
end
1863
function _insert!(a::Vector{T}, i::Integer, item::T) where T
1864
    @_noub_meta
1,940,255✔
1865
    # Throw convert error before changing the shape of the array
1866
    _growat!(a, i, 1)
2,595,109✔
1867
    # :noub, because _growat! already did bound check
1868
    @inbounds a[i] = item
2,595,103✔
1869
    return a
2,595,103✔
1870
end
1871

1872
"""
1873
    deleteat!(a::Vector, i::Integer)
1874

1875
Remove the item at the given `i` and return the modified `a`. Subsequent items
1876
are shifted to fill the resulting gap.
1877

1878
See also [`keepat!`](@ref), [`delete!`](@ref), [`popat!`](@ref), [`splice!`](@ref).
1879

1880
# Examples
1881
```jldoctest
1882
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1883
5-element Vector{Int64}:
1884
 6
1885
 4
1886
 3
1887
 2
1888
 1
1889
```
1890
"""
1891
function deleteat!(a::Vector, i::Integer)
807✔
1892
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
137,951✔
1893
    _deleteat!(a, i, 1)
143,167✔
1894
    return a
137,951✔
1895
end
1896

1897
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
102,263✔
1898
    if eltype(r) === Bool
326,779✔
1899
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
18✔
1900
    else
1901
        f = first(r)
326,779✔
1902
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
326,761✔
1903
        isempty(r) || _deleteat!(a, f, length(r))
643,042✔
1904
        return a
327,196✔
1905
    end
1906
end
1907

1908
"""
1909
    deleteat!(a::Vector, inds)
1910

1911
Remove the items at the indices given by `inds`, and return the modified `a`.
1912
Subsequent items are shifted to fill the resulting gap.
1913

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

1917
# Examples
1918
```jldoctest
1919
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1920
3-element Vector{Int64}:
1921
 5
1922
 3
1923
 1
1924

1925
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1926
3-element Vector{Int64}:
1927
 5
1928
 3
1929
 1
1930

1931
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1932
ERROR: ArgumentError: indices must be unique and sorted
1933
Stacktrace:
1934
[...]
1935
```
1936
"""
1937
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
57✔
1938
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
108,829✔
1939

1940
struct Nowhere; end
232✔
1941
push!(::Nowhere, _) = nothing
4,475,174✔
1942
_growend!(::Nowhere, _) = nothing
×
1943

1944
function _push_deleted!(dltd, a::Vector, ind)
1945
    @_propagate_inbounds_meta
4,475,180✔
1946
    if isassigned(a, ind)
4,475,180✔
1947
        push!(dltd, a[ind])
4,475,224✔
1948
    else
1949
        _growend!(dltd, 1)
×
1950
    end
1951
end
1952

1953
function _copy_item!(a::Vector, p, q)
1954
    @_propagate_inbounds_meta
13,134,969✔
1955
    if isassigned(a, q)
13,134,969✔
1956
        a[p] = a[q]
13,134,969✔
1957
    else
1958
        _unsetindex!(a, p)
×
1959
    end
1960
end
1961

1962
function _deleteat!(a::Vector, inds, dltd=Nowhere())
107,374✔
1963
    n = length(a)
216,260✔
1964
    y = iterate(inds)
107,404✔
1965
    y === nothing && return a
107,374✔
1966
    (p, s) = y
106,426✔
1967
    checkbounds(a, p)
106,438✔
1968
    @inbounds _push_deleted!(dltd, a, p)
106,426✔
1969
    q = p+1
106,414✔
1970
    while true
4,475,180✔
1971
        y = iterate(inds, s)
4,475,213✔
1972
        y === nothing && break
4,475,180✔
1973
        (i,s) = y
4,368,772✔
1974
        if !(q <= i <= n)
4,368,772✔
1975
            if i < q
6✔
1976
                _throw_argerror("indices must be unique and sorted")
3✔
1977
            else
1978
                throw(BoundsError())
3✔
1979
            end
1980
        end
1981
        while q < i
8,635,028✔
1982
            @inbounds _copy_item!(a, p, q)
4,266,262✔
1983
            p += 1; q += 1
4,266,262✔
1984
        end
4,266,262✔
1985
        @inbounds _push_deleted!(dltd, a, i)
4,368,798✔
1986
        q = i+1
4,368,766✔
1987
    end
4,368,766✔
1988
    while q <= n
8,848,533✔
1989
        @inbounds _copy_item!(a, p, q)
8,742,125✔
1990
        p += 1; q += 1
8,742,125✔
1991
    end
8,742,125✔
1992
    _deleteend!(a, n-p+1)
4,475,174✔
1993
    return a
106,408✔
1994
end
1995

1996
# Simpler and more efficient version for logical indexing
1997
function deleteat!(a::Vector, inds::AbstractVector{Bool})
12,087✔
1998
    n = length(a)
12,087✔
1999
    length(inds) == n || throw(BoundsError(a, inds))
12,102✔
2000
    p = 1
12,072✔
2001
    for (q, i) in enumerate(inds)
24,141✔
2002
        @inbounds _copy_item!(a, p, q)
126,582✔
2003
        p += !i
126,582✔
2004
    end
241,095✔
2005
    _deleteend!(a, n-p+1)
64,059✔
2006
    return a
12,072✔
2007
end
2008

2009
const _default_splice = []
2010

2011
"""
2012
    splice!(a::Vector, index::Integer, [replacement]) -> item
2013

2014
Remove the item at the given index, and return the removed item.
2015
Subsequent items are shifted left to fill the resulting gap.
2016
If specified, replacement values from an ordered
2017
collection will be spliced in place of the removed item.
2018

2019
See also [`replace`](@ref), [`delete!`](@ref), [`deleteat!`](@ref), [`pop!`](@ref), [`popat!`](@ref).
2020

2021
# Examples
2022
```jldoctest
2023
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
2024
2
2025

2026
julia> A
2027
5-element Vector{Int64}:
2028
 6
2029
 5
2030
 4
2031
 3
2032
 1
2033

2034
julia> splice!(A, 5, -1)
2035
1
2036

2037
julia> A
2038
5-element Vector{Int64}:
2039
  6
2040
  5
2041
  4
2042
  3
2043
 -1
2044

2045
julia> splice!(A, 1, [-1, -2, -3])
2046
6
2047

2048
julia> A
2049
7-element Vector{Int64}:
2050
 -1
2051
 -2
2052
 -3
2053
  5
2054
  4
2055
  3
2056
 -1
2057
```
2058

2059
To insert `replacement` before an index `n` without removing any items, use
2060
`splice!(collection, n:n-1, replacement)`.
2061
"""
2062
function splice!(a::Vector, i::Integer, ins=_default_splice)
11,077✔
2063
    v = a[i]
11,132✔
2064
    m = length(ins)
10,249✔
2065
    if m == 0
10,249✔
2066
        _deleteat!(a, i, 1)
1,624✔
2067
    elseif m == 1
8,625✔
2068
        a[i] = only(ins)
798✔
2069
    else
2070
        _growat!(a, i, m-1)
7,827✔
2071
        k = 1
7,827✔
2072
        for x in ins
7,827✔
2073
            a[i+k-1] = x
999,855✔
2074
            k += 1
999,855✔
2075
        end
999,855✔
2076
    end
2077
    return v
10,249✔
2078
end
2079

2080
"""
2081
    splice!(a::Vector, indices, [replacement]) -> items
2082

2083
Remove items at specified indices, and return a collection containing
2084
the removed items.
2085
Subsequent items are shifted left to fill the resulting gaps.
2086
If specified, replacement values from an ordered collection will be spliced in
2087
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
2088

2089
To insert `replacement` before an index `n` without removing any items, use
2090
`splice!(collection, n:n-1, replacement)`.
2091

2092
$(_DOCS_ALIASING_WARNING)
2093

2094
!!! compat "Julia 1.5"
2095
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
2096

2097
!!! compat "Julia 1.8"
2098
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
2099

2100
# Examples
2101
```jldoctest
2102
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
2103
Int64[]
2104

2105
julia> A
2106
8-element Vector{Int64}:
2107
 -1
2108
 -2
2109
 -3
2110
  2
2111
  5
2112
  4
2113
  3
2114
 -1
2115
```
2116
"""
2117
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
501,917✔
2118
    v = a[r]
712,607✔
2119
    m = length(ins)
400,103✔
2120
    if m == 0
400,103✔
2121
        deleteat!(a, r)
222,177✔
2122
        return v
111,270✔
2123
    end
2124

2125
    n = length(a)
288,833✔
2126
    f = first(r)
288,833✔
2127
    l = last(r)
288,833✔
2128
    d = length(r)
288,833✔
2129

2130
    if m < d
288,833✔
2131
        delta = d - m
38,055✔
2132
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
57,399✔
2133
    elseif m > d
250,778✔
2134
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
250,454✔
2135
    end
2136

2137
    k = 1
288,833✔
2138
    for x in ins
323,351✔
2139
        a[f+k-1] = x
12,635,022✔
2140
        k += 1
12,635,022✔
2141
    end
16,846,584✔
2142
    return v
288,833✔
2143
end
2144

2145
splice!(a::Vector, inds) = (dltds = eltype(a)[]; _deleteat!(a, inds, dltds); dltds)
3✔
2146

2147
function empty!(a::Vector)
335✔
2148
    _deleteend!(a, length(a))
6,474,694✔
2149
    return a
5,398,431✔
2150
end
2151

2152
# use memcmp for cmp on byte arrays
2153
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
2154
    aref = a.ref
696✔
2155
    bref = b.ref
696✔
2156
    ta = @_gc_preserve_begin aref
696✔
2157
    tb = @_gc_preserve_begin bref
696✔
2158
    pa = unsafe_convert(Ptr{Cvoid}, aref)
696✔
2159
    pb = unsafe_convert(Ptr{Cvoid}, bref)
696✔
2160
    c = memcmp(pa, pb, min(length(a),length(b)))
696✔
2161
    @_gc_preserve_end ta
696✔
2162
    @_gc_preserve_end tb
696✔
2163
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
1,084✔
2164
end
2165

2166
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2167
# use memcmp for == on bit integer types
2168
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
4,671✔
2169
    if size(a) == size(b)
14,070✔
2170
        aref = a.ref
7,128✔
2171
        bref = b.ref
7,128✔
2172
        ta = @_gc_preserve_begin aref
7,128✔
2173
        tb = @_gc_preserve_begin bref
7,128✔
2174
        pa = unsafe_convert(Ptr{Cvoid}, aref)
7,128✔
2175
        pb = unsafe_convert(Ptr{Cvoid}, bref)
7,128✔
2176
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
7,128✔
2177
        @_gc_preserve_end ta
7,128✔
2178
        @_gc_preserve_end tb
7,128✔
2179
        return c == 0
7,128✔
2180
    else
2181
        return false
×
2182
    end
2183
end
2184

2185
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
481✔
2186
    len = length(a)
1,926,285✔
2187
    if len == length(b)
1,926,285✔
2188
        aref = a.ref
1,920,018✔
2189
        bref = b.ref
1,919,842✔
2190
        ta = @_gc_preserve_begin aref
1,920,018✔
2191
        tb = @_gc_preserve_begin bref
1,920,018✔
2192
        T = eltype(Arr)
601✔
2193
        pa = unsafe_convert(Ptr{T}, aref)
1,920,018✔
2194
        pb = unsafe_convert(Ptr{T}, bref)
1,920,018✔
2195
        c = memcmp(pa, pb, sizeof(T) * len)
1,920,018✔
2196
        @_gc_preserve_end ta
1,920,018✔
2197
        @_gc_preserve_end tb
1,920,018✔
2198
        return c == 0
1,920,018✔
2199
    else
2200
        return false
6,267✔
2201
    end
2202
end
2203

2204
"""
2205
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2206

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

2210
# Examples
2211
```jldoctest
2212
julia> A = Vector(1:5)
2213
5-element Vector{Int64}:
2214
 1
2215
 2
2216
 3
2217
 4
2218
 5
2219

2220
julia> reverse(A)
2221
5-element Vector{Int64}:
2222
 5
2223
 4
2224
 3
2225
 2
2226
 1
2227

2228
julia> reverse(A, 1, 4)
2229
5-element Vector{Int64}:
2230
 4
2231
 3
2232
 2
2233
 1
2234
 5
2235

2236
julia> reverse(A, 3, 5)
2237
5-element Vector{Int64}:
2238
 1
2239
 2
2240
 5
2241
 4
2242
 3
2243
```
2244
"""
2245
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
200,947✔
2246
    s, n = Int(start), Int(stop)
200,947✔
2247
    B = similar(A)
210,124✔
2248
    for i = firstindex(A):s-1
200,950✔
2249
        B[i] = A[i]
5,031✔
2250
    end
9,198✔
2251
    for i = s:n
202,604✔
2252
        B[i] = A[n+s-i]
722,151✔
2253
    end
1,243,373✔
2254
    for i = n+1:lastindex(A)
399,385✔
2255
        B[i] = A[i]
5,040✔
2256
    end
9,216✔
2257
    return B
200,947✔
2258
end
2259

2260
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2261
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2262
    @eval begin
2263
        $f(A::AbstractVector; dims::D=:) where {D} = $_f(A, dims)
11,514,743✔
2264
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
4,392,346✔
2265
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2266
        function $_f(A::AbstractVector, dim::Integer)
2267
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
33✔
2268
            return $_f(A, :)
12✔
2269
        end
2270
    end
2271
end
2272

2273
function reverseind(a::AbstractVector, i::Integer)
9✔
2274
    li = LinearIndices(a)
9✔
2275
    first(li) + last(li) - i
9✔
2276
end
2277

2278
# This implementation of `midpoint` is performance-optimized but safe
2279
# only if `lo <= hi`.
2280
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
103,276,228✔
2281
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2282

2283
"""
2284
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2285

2286
In-place version of [`reverse`](@ref).
2287

2288
# Examples
2289
```jldoctest
2290
julia> A = Vector(1:5)
2291
5-element Vector{Int64}:
2292
 1
2293
 2
2294
 3
2295
 4
2296
 5
2297

2298
julia> reverse!(A);
2299

2300
julia> A
2301
5-element Vector{Int64}:
2302
 5
2303
 4
2304
 3
2305
 2
2306
 1
2307
```
2308
"""
2309
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
7,110,314✔
2310
    s, n = Int(start), Int(stop)
16,596,503✔
2311
    if n > s # non-empty and non-trivial
7,110,305✔
2312
        liv = LinearIndices(v)
248,278✔
2313
        if !(first(liv) ≤ s ≤ last(liv))
248,278✔
2314
            throw(BoundsError(v, s))
6✔
2315
        elseif !(first(liv) ≤ n ≤ last(liv))
248,272✔
2316
            throw(BoundsError(v, n))
×
2317
        end
2318
        r = n
248,272✔
2319
        @inbounds for i in s:midpoint(s, n-1)
451,084✔
2320
            v[i], v[r] = v[r], v[i]
23,407,507✔
2321
            r -= 1
23,407,507✔
2322
        end
46,566,742✔
2323
    end
2324
    return v
7,110,299✔
2325
end
2326

2327
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2328

2329
vcat() = Vector{Any}()
60,467✔
2330
hcat() = Vector{Any}()
3✔
2331

2332
function hcat(V::Vector{T}...) where T
188✔
2333
    height = length(V[1])
1,709✔
2334
    for j = 2:length(V)
1,709✔
2335
        if length(V[j]) != height
1,907✔
2336
            throw(DimensionMismatch("vectors must have same lengths"))
3✔
2337
        end
2338
    end
2,198✔
2339
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
1,706✔
2340
end
2341
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
18✔
2342

2343
function vcat(arrays::Vector{T}...) where T
1,393,133✔
2344
    n = 0
1,393,231✔
2345
    for a in arrays
1,393,231✔
2346
        n += length(a)
8,787,149✔
2347
    end
10,180,195✔
2348
    arr = Vector{T}(undef, n)
1,393,231✔
2349
    nd = 1
1,393,231✔
2350
    for a in arrays
1,393,231✔
2351
        na = length(a)
8,787,149✔
2352
        @assert nd + na <= 1 + length(arr) "Concurrent modification of arrays?"
8,787,149✔
2353
        unsafe_copyto!(arr, nd, a, 1, na)
17,572,589✔
2354
        nd += na
8,787,149✔
2355
    end
10,180,195✔
2356
    return arr
1,393,231✔
2357
end
2358
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
108✔
2359

2360
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))
3✔
2361

2362
## find ##
2363

2364
"""
2365
    findnext(A, i)
2366

2367
Find the next index after or including `i` of a `true` element of `A`,
2368
or `nothing` if not found.
2369

2370
Indices are of the same type as those returned by [`keys(A)`](@ref)
2371
and [`pairs(A)`](@ref).
2372

2373
# Examples
2374
```jldoctest
2375
julia> A = [false, false, true, false]
2376
4-element Vector{Bool}:
2377
 0
2378
 0
2379
 1
2380
 0
2381

2382
julia> findnext(A, 1)
2383
3
2384

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

2387
julia> A = [false false; true false]
2388
2×2 Matrix{Bool}:
2389
 0  0
2390
 1  0
2391

2392
julia> findnext(A, CartesianIndex(1, 1))
2393
CartesianIndex(2, 1)
2394
```
2395
"""
2396
findnext(A, start) = findnext(identity, A, start)
232,127✔
2397

2398
"""
2399
    findfirst(A)
2400

2401
Return the index or key of the first `true` value in `A`.
2402
Return `nothing` if no such value is found.
2403
To search for other kinds of values, pass a predicate as the first argument.
2404

2405
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2406
and [`pairs(A)`](@ref).
2407

2408
See also [`findall`](@ref), [`findnext`](@ref), [`findlast`](@ref), [`searchsortedfirst`](@ref).
2409

2410
# Examples
2411
```jldoctest
2412
julia> A = [false, false, true, false]
2413
4-element Vector{Bool}:
2414
 0
2415
 0
2416
 1
2417
 0
2418

2419
julia> findfirst(A)
2420
3
2421

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

2424
julia> A = [false false; true false]
2425
2×2 Matrix{Bool}:
2426
 0  0
2427
 1  0
2428

2429
julia> findfirst(A)
2430
CartesianIndex(2, 1)
2431
```
2432
"""
2433
findfirst(A) = findfirst(identity, A)
3,732✔
2434

2435
# Needed for bootstrap, and allows defining only an optimized findnext method
2436
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
143,896✔
2437

2438
"""
2439
    findnext(predicate::Function, A, i)
2440

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

2446
Indices are of the same type as those returned by [`keys(A)`](@ref)
2447
and [`pairs(A)`](@ref).
2448

2449
# Examples
2450
```jldoctest
2451
julia> A = [1, 4, 2, 2];
2452

2453
julia> findnext(isodd, A, 1)
2454
1
2455

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

2458
julia> A = [1 4; 2 2];
2459

2460
julia> findnext(isodd, A, CartesianIndex(1, 1))
2461
CartesianIndex(1, 1)
2462

2463
julia> findnext(isspace, "a b c", 3)
2464
4
2465
```
2466
"""
2467
function findnext(testf::Function, A, start)
17,782✔
2468
    i = oftype(first(keys(A)), start)
775,399✔
2469
    l = last(keys(A))
939,773✔
2470
    i > l && return nothing
939,773✔
2471
    while true
2,692,049✔
2472
        testf(A[i]) && return i
3,100,574✔
2473
        i == l && break
2,378,669✔
2474
        # nextind(A, l) can throw/overflow
2475
        i = nextind(A, i)
2,201,912✔
2476
    end
2,201,855✔
2477
    return nothing
176,742✔
2478
end
2479

2480
"""
2481
    findfirst(predicate::Function, A)
2482

2483
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2484
Return `nothing` if there is no such element.
2485

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

2489
# Examples
2490
```jldoctest
2491
julia> A = [1, 4, 2, 2]
2492
4-element Vector{Int64}:
2493
 1
2494
 4
2495
 2
2496
 2
2497

2498
julia> findfirst(iseven, A)
2499
2
2500

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

2503
julia> findfirst(isequal(4), A)
2504
2
2505

2506
julia> A = [1 4; 2 2]
2507
2×2 Matrix{Int64}:
2508
 1  4
2509
 2  2
2510

2511
julia> findfirst(iseven, A)
2512
CartesianIndex(2, 1)
2513
```
2514
"""
2515
function findfirst(testf::Function, A)
3,766✔
2516
    for (i, a) in pairs(A)
7,447✔
2517
        testf(a) && return i
7,554✔
2518
    end
11,397✔
2519
    return nothing
3,745✔
2520
end
2521

2522
# Needed for bootstrap, and allows defining only an optimized findnext method
2523
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
13,460,235✔
2524
    findnext(testf, A, first(keys(A)))
2525

2526
findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::OneTo) where {T<:Integer} =
18✔
2527
    1 <= p.x <= r.stop ? convert(keytype(r), p.x) : nothing
2528

2529
findfirst(::typeof(iszero), ::OneTo) = nothing
6✔
2530
findfirst(::typeof(isone), r::OneTo) = isempty(r) ? nothing : oneunit(keytype(r))
15✔
2531

2532
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::AbstractUnitRange{<:Integer}) where {T<:Integer}
18✔
2533
    first(r) <= p.x <= last(r) || return nothing
87✔
2534
    i1 = first(keys(r))
27✔
2535
    return i1 + oftype(i1, p.x - first(r))
27✔
2536
end
2537

2538
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
453✔
2539
    isempty(r) && return nothing
453✔
2540
    minimum(r) <= p.x <= maximum(r) || return nothing
576✔
2541
    d = p.x - first(r)
318✔
2542
    iszero(d % step(r)) || return nothing
426✔
2543
    return convert(keytype(r), d ÷ step(r) + 1)
210✔
2544
end
2545

2546
findfirst(::typeof(iszero), r::AbstractRange) = findfirst(==(zero(first(r))), r)
390✔
2547
findfirst(::typeof(isone), r::AbstractRange) = findfirst(==(one(first(r))), r)
9✔
2548

2549
"""
2550
    findprev(A, i)
2551

2552
Find the previous index before or including `i` of a `true` element of `A`,
2553
or `nothing` if not found.
2554

2555
Indices are of the same type as those returned by [`keys(A)`](@ref)
2556
and [`pairs(A)`](@ref).
2557

2558
See also [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2559

2560
# Examples
2561
```jldoctest
2562
julia> A = [false, false, true, true]
2563
4-element Vector{Bool}:
2564
 0
2565
 0
2566
 1
2567
 1
2568

2569
julia> findprev(A, 3)
2570
3
2571

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

2574
julia> A = [false false; true true]
2575
2×2 Matrix{Bool}:
2576
 0  0
2577
 1  1
2578

2579
julia> findprev(A, CartesianIndex(2, 1))
2580
CartesianIndex(2, 1)
2581
```
2582
"""
2583
findprev(A, start) = findprev(identity, A, start)
29,889✔
2584

2585
"""
2586
    findlast(A)
2587

2588
Return the index or key of the last `true` value in `A`.
2589
Return `nothing` if there is no `true` value in `A`.
2590

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

2594
See also [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2595

2596
# Examples
2597
```jldoctest
2598
julia> A = [true, false, true, false]
2599
4-element Vector{Bool}:
2600
 1
2601
 0
2602
 1
2603
 0
2604

2605
julia> findlast(A)
2606
3
2607

2608
julia> A = falses(2,2);
2609

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

2612
julia> A = [true false; true false]
2613
2×2 Matrix{Bool}:
2614
 1  0
2615
 1  0
2616

2617
julia> findlast(A)
2618
CartesianIndex(2, 1)
2619
```
2620
"""
2621
findlast(A) = findlast(identity, A)
141✔
2622

2623
# Needed for bootstrap, and allows defining only an optimized findprev method
2624
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
5,172✔
2625

2626
"""
2627
    findprev(predicate::Function, A, i)
2628

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

2634
Indices are of the same type as those returned by [`keys(A)`](@ref)
2635
and [`pairs(A)`](@ref).
2636

2637
# Examples
2638
```jldoctest
2639
julia> A = [4, 6, 1, 2]
2640
4-element Vector{Int64}:
2641
 4
2642
 6
2643
 1
2644
 2
2645

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

2648
julia> findprev(isodd, A, 3)
2649
3
2650

2651
julia> A = [4 6; 1 2]
2652
2×2 Matrix{Int64}:
2653
 4  6
2654
 1  2
2655

2656
julia> findprev(isodd, A, CartesianIndex(1, 2))
2657
CartesianIndex(2, 1)
2658

2659
julia> findprev(isspace, "a b c", 3)
2660
2
2661
```
2662
"""
2663
function findprev(testf::Function, A, start)
789✔
2664
    f = first(keys(A))
28,124✔
2665
    i = oftype(f, start)
28,157✔
2666
    i < f && return nothing
28,124✔
2667
    while true
455,382✔
2668
        testf(A[i]) && return i
455,992✔
2669
        i == f && break
427,757✔
2670
        # prevind(A, f) can throw/underflow
2671
        i = prevind(A, i)
427,342✔
2672
    end
427,258✔
2673
    return nothing
406✔
2674
end
2675

2676
"""
2677
    findlast(predicate::Function, A)
2678

2679
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2680
Return `nothing` if there is no such element.
2681

2682
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2683
and [`pairs(A)`](@ref).
2684

2685
# Examples
2686
```jldoctest
2687
julia> A = [1, 2, 3, 4]
2688
4-element Vector{Int64}:
2689
 1
2690
 2
2691
 3
2692
 4
2693

2694
julia> findlast(isodd, A)
2695
3
2696

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

2699
julia> A = [1 2; 3 4]
2700
2×2 Matrix{Int64}:
2701
 1  2
2702
 3  4
2703

2704
julia> findlast(isodd, A)
2705
CartesianIndex(2, 1)
2706
```
2707
"""
2708
function findlast(testf::Function, A)
9✔
2709
    for (i, a) in Iterators.reverse(pairs(A))
12✔
2710
        testf(a) && return i
18✔
2711
    end
18✔
2712
    return nothing
6✔
2713
end
2714

2715
# Needed for bootstrap, and allows defining only an optimized findprev method
2716
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
1,197,611✔
2717
    findprev(testf, A, last(keys(A)))
2718

2719
# for monotonic ranges, there is a unique index corresponding to a value, so findfirst and findlast are identical
2720
function findlast(p::Union{Fix2{typeof(isequal),<:Integer},Fix2{typeof(==),<:Integer},typeof(iszero),typeof(isone)},
39✔
2721
        r::AbstractUnitRange{<:Integer})
2722
    findfirst(p, r)
42✔
2723
end
2724

2725
function findlast(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T},typeof(iszero),typeof(isone)},
27✔
2726
        r::StepRange{T,S}) where {T,S}
2727
    findfirst(p, r)
27✔
2728
end
2729

2730
"""
2731
    findall(f::Function, A)
2732

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

2736
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2737
and [`pairs(A)`](@ref).
2738

2739
# Examples
2740
```jldoctest
2741
julia> x = [1, 3, 4]
2742
3-element Vector{Int64}:
2743
 1
2744
 3
2745
 4
2746

2747
julia> findall(isodd, x)
2748
2-element Vector{Int64}:
2749
 1
2750
 2
2751

2752
julia> A = [1 2 0; 3 4 0]
2753
2×3 Matrix{Int64}:
2754
 1  2  0
2755
 3  4  0
2756
julia> findall(isodd, A)
2757
2-element Vector{CartesianIndex{2}}:
2758
 CartesianIndex(1, 1)
2759
 CartesianIndex(2, 1)
2760

2761
julia> findall(!iszero, A)
2762
4-element Vector{CartesianIndex{2}}:
2763
 CartesianIndex(1, 1)
2764
 CartesianIndex(2, 1)
2765
 CartesianIndex(1, 2)
2766
 CartesianIndex(2, 2)
2767

2768
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2769
Dict{Symbol, Int64} with 3 entries:
2770
  :A => 10
2771
  :B => -1
2772
  :C => 0
2773

2774
julia> findall(≥(0), d)
2775
2-element Vector{Symbol}:
2776
 :A
2777
 :C
2778

2779
```
2780
"""
2781
function findall(testf::Function, A)
108✔
2782
    gen = (first(p) for p in pairs(A) if testf(last(p)))
129✔
2783
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
129✔
2784
end
2785

2786
# Broadcasting is much faster for small testf, and computing
2787
# integer indices from logical index using findall has a negligible cost
2788
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
1,015✔
2789

2790
"""
2791
    findall(A)
2792

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

2797
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2798
and [`pairs(A)`](@ref).
2799

2800
See also [`findfirst`](@ref), [`searchsorted`](@ref).
2801

2802
# Examples
2803
```jldoctest
2804
julia> A = [true, false, false, true]
2805
4-element Vector{Bool}:
2806
 1
2807
 0
2808
 0
2809
 1
2810

2811
julia> findall(A)
2812
2-element Vector{Int64}:
2813
 1
2814
 4
2815

2816
julia> A = [true false; false true]
2817
2×2 Matrix{Bool}:
2818
 1  0
2819
 0  1
2820

2821
julia> findall(A)
2822
2-element Vector{CartesianIndex{2}}:
2823
 CartesianIndex(1, 1)
2824
 CartesianIndex(2, 2)
2825

2826
julia> findall(falses(3))
2827
Int64[]
2828
```
2829
"""
2830
function findall(A)
12✔
2831
    collect(first(p) for p in pairs(A) if last(p))
12✔
2832
end
2833

2834
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2835
function findall(A::AbstractArray{Bool})
104✔
2836
    n = count(A)
11,045✔
2837
    I = Vector{eltype(keys(A))}(undef, n)
11,030✔
2838
    cnt = 1
11,030✔
2839
    for (i,a) in pairs(A)
22,036✔
2840
        if a
625,323✔
2841
            I[cnt] = i
384,007✔
2842
            cnt += 1
384,007✔
2843
        end
2844
    end
1,239,631✔
2845
    I
11,030✔
2846
end
2847

2848
findall(x::Bool) = x ? [1] : Vector{Int}()
×
2849
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
6✔
2850
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
6✔
2851

2852
# similar to Matlab's ismember
2853
"""
2854
    indexin(a, b)
2855

2856
Return an array containing the first index in `b` for
2857
each value in `a` that is a member of `b`. The output
2858
array contains `nothing` wherever `a` is not a member of `b`.
2859

2860
See also [`sortperm`](@ref), [`findfirst`](@ref).
2861

2862
# Examples
2863
```jldoctest
2864
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2865

2866
julia> b = ['a', 'b', 'c'];
2867

2868
julia> indexin(a, b)
2869
6-element Vector{Union{Nothing, Int64}}:
2870
 1
2871
 2
2872
 3
2873
 2
2874
  nothing
2875
 1
2876

2877
julia> indexin(b, a)
2878
3-element Vector{Union{Nothing, Int64}}:
2879
 1
2880
 2
2881
 3
2882
```
2883
"""
2884
function indexin(a, b::AbstractArray)
27✔
2885
    inds = keys(b)
27✔
2886
    bdict = Dict{eltype(b),eltype(inds)}()
27✔
2887
    for (val, ind) in zip(b, inds)
51✔
2888
        get!(bdict, val, ind)
111✔
2889
    end
198✔
2890
    return Union{eltype(inds), Nothing}[
27✔
2891
        get(bdict, i, nothing) for i in a
2892
    ]
2893
end
2894

2895
function _findin(a::Union{AbstractArray, Tuple}, b::AbstractSet)
1,125✔
2896
    ind  = Vector{eltype(keys(a))}()
1,683✔
2897
    @inbounds for (i,ai) in pairs(a)
1,818✔
2898
        ai in b && push!(ind, i)
271,689✔
2899
    end
541,695✔
2900
    ind
1,125✔
2901
end
2902
_findin(a::Union{AbstractArray, Tuple}, b) = _findin(a, Set(b))
1,125✔
2903

2904
# If two collections are already sorted, _findin can be computed with
2905
# a single traversal of the two collections. This is much faster than
2906
# using a hash table (although it has the same complexity).
2907
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
27✔
2908
    viter, witer = keys(v), eachindex(w)
27✔
2909
    out  = eltype(viter)[]
27✔
2910
    vy, wy = iterate(viter), iterate(witer)
33✔
2911
    if vy === nothing || wy === nothing
51✔
2912
        return out
6✔
2913
    end
2914
    viteri, i = vy
21✔
2915
    witerj, j = wy
21✔
2916
    @inbounds begin
21✔
2917
        vi, wj = v[viteri], w[witerj]
21✔
2918
        while true
162✔
2919
            if isless(vi, wj)
168✔
2920
                vy = iterate(viter, i)
75✔
2921
                if vy === nothing
42✔
2922
                    break
6✔
2923
                end
2924
                viteri, i = vy
36✔
2925
                vi        = v[viteri]
36✔
2926
            elseif isless(wj, vi)
120✔
2927
                wy = iterate(witer, j)
132✔
2928
                if wy === nothing
72✔
2929
                    break
12✔
2930
                end
2931
                witerj, j = wy
60✔
2932
                wj        = w[witerj]
60✔
2933
            else
2934
                push!(out, viteri)
48✔
2935
                vy = iterate(viter, i)
75✔
2936
                if vy === nothing
48✔
2937
                    break
3✔
2938
                end
2939
                # We only increment the v iterator because v can have
2940
                # repeated matches to a single value in w
2941
                viteri, i = vy
45✔
2942
                vi        = v[viteri]
45✔
2943
            end
2944
        end
141✔
2945
    end
2946
    return out
21✔
2947
end
2948

2949
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
45✔
2950
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
75✔
2951
        return _sortedfindin(x, pred.x)
27✔
2952
    else
2953
        return _findin(x, pred.x)
18✔
2954
    end
2955
end
2956
# issorted fails for some element types so the method above has to be restricted
2957
# to element with isless/< defined.
2958
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
1,119✔
2959
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2960

2961
# Copying subregions
2962
function indcopy(sz::Dims, I::Vector)
3✔
2963
    n = length(I)
3✔
2964
    s = sz[n]
3✔
2965
    for i = n+1:length(sz)
6✔
2966
        s *= sz[i]
×
2967
    end
×
2968
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
6✔
2969
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
6✔
2970
    dst, src
3✔
2971
end
2972

2973
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
3✔
2974
    n = length(I)
3✔
2975
    _s = sz[n]
3✔
2976
    for i = n+1:length(sz)
3✔
2977
        _s *= sz[i]
×
2978
    end
×
2979
    s = _s
3✔
2980
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
9✔
2981
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
9✔
2982
    dst, src
3✔
2983
end
2984

2985
## Filter ##
2986

2987
"""
2988
    filter(f, a)
2989

2990
Return a copy of collection `a`, removing elements for which `f` is `false`.
2991
The function `f` is passed one argument.
2992

2993
!!! compat "Julia 1.4"
2994
    Support for `a` as a tuple requires at least Julia 1.4.
2995

2996
See also [`filter!`](@ref), [`Iterators.filter`](@ref).
2997

2998
# Examples
2999
```jldoctest
3000
julia> a = 1:10
3001
1:10
3002

3003
julia> filter(isodd, a)
3004
5-element Vector{Int64}:
3005
 1
3006
 3
3007
 5
3008
 7
3009
 9
3010
```
3011
"""
3012
function filter(f, a::Array{T, N}) where {T, N}
6,949,010✔
3013
    j = 1
6,949,010✔
3014
    b = Vector{T}(undef, length(a))
6,949,010✔
3015
    for ai in a
6,949,010✔
3016
        @inbounds b[j] = ai
20,137,332✔
3017
        j = ifelse(f(ai)::Bool, j+1, j)
20,141,476✔
3018
    end
20,137,332✔
3019
    resize!(b, j-1)
6,949,010✔
3020
    sizehint!(b, length(b))
6,949,010✔
3021
    b
6,949,010✔
3022
end
3023

3024
function filter(f, a::AbstractArray)
242✔
3025
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
242✔
3026

3027
    j = 1
242✔
3028
    idxs = Vector{Int}(undef, length(a))
251✔
3029
    for idx in eachindex(a)
251✔
3030
        @inbounds idxs[j] = idx
233,082✔
3031
        ai = @inbounds a[idx]
233,082✔
3032
        j = ifelse(f(ai)::Bool, j+1, j)
237,681✔
3033
    end
465,925✔
3034
    resize!(idxs, j-1)
239✔
3035
    res = a[idxs]
239✔
3036
    empty!(idxs)
9,549✔
3037
    sizehint!(idxs, 0)
239✔
3038
    return res
239✔
3039
end
3040

3041
"""
3042
    filter!(f, a)
3043

3044
Update collection `a`, removing elements for which `f` is `false`.
3045
The function `f` is passed one argument.
3046

3047
# Examples
3048
```jldoctest
3049
julia> filter!(isodd, Vector(1:10))
3050
5-element Vector{Int64}:
3051
 1
3052
 3
3053
 5
3054
 7
3055
 9
3056
```
3057
"""
3058
function filter!(f, a::AbstractVector)
2,785,989✔
3059
    j = firstindex(a)
2,809,356✔
3060
    for ai in a
2,809,392✔
3061
        @inbounds a[j] = ai
10,208,589✔
3062
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
10,788,427✔
3063
    end
10,208,616✔
3064
    j > lastindex(a) && return a
2,809,389✔
3065
    if a isa Vector
1,670,052✔
3066
        resize!(a, j-1)
1,666,335✔
3067
        sizehint!(a, j-1)
1,666,335✔
3068
    else
3069
        deleteat!(a, j:lastindex(a))
7,497✔
3070
    end
3071
    return a
1,670,085✔
3072
end
3073

3074
"""
3075
    filter(f)
3076

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

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

3083
# Examples
3084
```jldoctest
3085
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
3086
(1, 2, 4, 6)
3087

3088
julia> map(filter(iseven), [1:3, 2:4, 3:5])
3089
3-element Vector{Vector{Int64}}:
3090
 [2]
3091
 [2, 4]
3092
 [4]
3093
```
3094
!!! compat "Julia 1.9"
3095
    This method requires at least Julia 1.9.
3096
"""
3097
function filter(f)
3✔
3098
    Fix1(filter, f)
3✔
3099
end
3100

3101
"""
3102
    keepat!(a::Vector, inds)
3103
    keepat!(a::BitVector, inds)
3104

3105
Remove the items at all the indices which are not given by `inds`,
3106
and return the modified `a`.
3107
Items which are kept are shifted to fill the resulting gaps.
3108

3109
$(_DOCS_ALIASING_WARNING)
3110

3111
`inds` must be an iterator of sorted and unique integer indices.
3112
See also [`deleteat!`](@ref).
3113

3114
!!! compat "Julia 1.7"
3115
    This function is available as of Julia 1.7.
3116

3117
# Examples
3118
```jldoctest
3119
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
3120
3-element Vector{Int64}:
3121
 6
3122
 4
3123
 2
3124
```
3125
"""
3126
keepat!(a::Vector, inds) = _keepat!(a, inds)
27✔
3127

3128
"""
3129
    keepat!(a::Vector, m::AbstractVector{Bool})
3130
    keepat!(a::BitVector, m::AbstractVector{Bool})
3131

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

3136
# Examples
3137
```jldoctest
3138
julia> a = [:a, :b, :c];
3139

3140
julia> keepat!(a, [true, false, true])
3141
2-element Vector{Symbol}:
3142
 :a
3143
 :c
3144

3145
julia> a
3146
2-element Vector{Symbol}:
3147
 :a
3148
 :c
3149
```
3150
"""
3151
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
450✔
3152

3153
# set-like operators for vectors
3154
# These are moderately efficient, preserve order, and remove dupes.
3155

3156
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
44,754✔
3157
    # P, U force specialization
3158
    if pred(x, state)
79,486✔
3159
        update!(state, x)
23,685✔
3160
        true
3161
    else
3162
        false
3163
    end
3164
end
3165

3166
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
830✔
3167
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
3,107✔
3168

3169
function _grow!(pred!, v::AbstractVector, itrs)
306✔
3170
    filter!(pred!, v) # uniquify v
894✔
3171
    for itr in itrs
894✔
3172
        mapfilter(pred!, push!, itr, v)
1,765✔
3173
    end
2,613✔
3174
    return v
894✔
3175
end
3176

3177
union!(v::AbstractVector{T}, itrs...) where {T} =
818✔
3178
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3179

3180
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
76✔
3181
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3182

3183
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
8✔
3184
    seen = Set{eltype(v)}()
12✔
3185
    filter!(_grow_filter!(seen), v)
12✔
3186
    shrinker!(seen, itrs...)
12✔
3187
    filter!(in(seen), v)
12✔
3188
end
3189

3190
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
6✔
3191
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
6✔
3192

3193
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
3,031✔
3194

3195
function intersect(itr, itrs...)
1,177✔
3196
    T = promote_eltype(itr, itrs...)
1,177✔
3197
    keep = intersect!(Set{T}(itr), itrs...)
1,177✔
3198
    vectorfilter(T, _shrink_filter!(keep), itr)
1,177✔
3199
end
3200

3201
function setdiff(itr, itrs...)
1,714✔
3202
    T = eltype(itr)
1,720✔
3203
    keep = setdiff!(Set{T}(itr), itrs...)
4,759✔
3204
    vectorfilter(T, _shrink_filter!(keep), itr)
1,720✔
3205
end
3206

3207
function intersect(v::AbstractVector, r::AbstractRange)
18✔
3208
    T = promote_eltype(v, r)
134✔
3209
    common = Iterators.filter(in(r), v)
134✔
3210
    seen = Set{T}(common)
134✔
3211
    return vectorfilter(T, _shrink_filter!(seen), common)
134✔
3212
end
3213
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
10✔
3214

3215
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3216
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
13,764✔
3217
    if i isa Bool # Not via dispatch to avoid ambiguities
1,835,197,490✔
3218
        throw(ArgumentError("invalid index: $i of type Bool"))
18✔
3219
    else
3220
        _getindex(v, i)
2,616,661,151✔
3221
    end
3222
end
3223

3224
"""
3225
    wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
3226

3227
Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version
3228
of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers.
3229
"""
3230
function wrap end
3231

3232
# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller
3233
function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N}
3234
    mem = ref.mem
156,495✔
3235
    mem_len = length(mem) + 1 - memoryrefoffset(ref)
156,495✔
3236
    len = Core.checked_dims(dims...)
155,601✔
3237
    @boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len)
156,504✔
3238
    return ref
155,592✔
3239
end
3240

3241
@noinline invalid_wrap_err(len, dims, proddims) = throw(DimensionMismatch(LazyString(
3✔
3242
    "Attempted to wrap a MemoryRef of length ", len, " with an Array of size dims=", dims,
3243
    " which is invalid because prod(dims) = ", proddims, " > ", len,
3244
    " so that the array would have more elements than the underlying memory can store.")))
3245

3246
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
12✔
3247
    dims = convert(Dims, dims)
12✔
3248
    ref = _wrap(m, dims)
12✔
3249
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
12✔
3250
end
3251

3252
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
9✔
3253
    dims = convert(Dims, dims)
9✔
3254
    ref = _wrap(memoryref(m), dims)
12✔
3255
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
6✔
3256
end
3257
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
12✔
3258
    dims = (Int(l),)
156,471✔
3259
    ref = _wrap(m, dims)
156,477✔
3260
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
155,571✔
3261
end
3262
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
3✔
3263
    dims = (Int(l),)
3✔
3264
    ref = _wrap(memoryref(m), (l,))
3✔
3265
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
3✔
3266
end
3267
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
113✔
3268
    ref = memoryref(m)
528,558✔
3269
    dims = (length(m),)
528,558✔
3270
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
413,734✔
3271
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