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

JuliaLang / julia / 1301

09 Oct 2025 08:00PM UTC coverage: 75.842% (-0.9%) from 76.72%
1301

push

buildkite

web-flow
ccall: make distinction of pointer vs name a syntactic distinction (#59165)

We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax, even though
it wasn't strictly enforced. And indeed, the other syntax forms weren't
handled reliably anyways (since doing so would require linearizing IR if
and only if the runtime values required it, which is not something that
is computable, and thus was often done wrong). This now intends to align
the runtime and compiler to expect only those syntax forms that we could
reliably handle in the past without errors, and adds explicit errors for
other cases, most of which we previously knew would be unreliable due to
reliance upon inference in making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall` also.

This fixes #57931, mostly by restricting the set of things that are
allowed to the set of things that have an obvious and pre-existing
behavior to be guaranteed to do that behavior. The hope is to PkgEval
this to check if any packages are doing something unusual and see if we
even need to allow anything else.

This drops support for https://github.com/JuliaLang/julia/pull/37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably still
unused.

The goal is to cause breakage only where the package authors really
failed to express intent with syntax, and otherwise to explicitly
maintain support by adding cases ... (continued)

20 of 35 new or added lines in 8 files covered. (57.14%)

721 existing lines in 81 files now uncovered.

60487 of 79754 relevant lines covered (75.84%)

7672511.81 hits per line

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

92.81
/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
4,022✔
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}()
203,131✔
159
function vect(X::T...) where T
10,188✔
160
    @_terminates_locally_meta
118,481✔
161
    vec = Vector{T}(undef, length(X))
129,709✔
162
    @_safeindex for i = 1:length(X)
137,189✔
163
        vec[i] = X[i]
283,412✔
164
    end
432,494✔
165
    return vec
125,483✔
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...)
405,110✔
184
    T = promote_typeof(X...)
405,432✔
185
    return T[X...]
405,614✔
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))
33,739✔
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)
×
207

208
function _unsetindex!(A::Array, i::Int)
1,317✔
209
    @inline
140,558,537✔
210
    @boundscheck checkbounds(A, i)
146,359,009✔
211
    @inbounds _unsetindex!(memoryref(A.ref, i))
146,753,861✔
212
    return A
141,293,744✔
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)
113,659,101✔
218
function elsize(::Type{Ptr{T}}) where T
7✔
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})
7✔
222
    T isa DataType || sizeof(Any) # throws
7✔
223
    return LLT_ALIGN(Core.sizeof(T), datatype_alignment(T))
5✔
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
82,460✔
228

229
function isassigned(a::Array, i::Int...)
46,300✔
230
    @inline
381,899✔
231
    @_noub_if_noinbounds_meta
381,899✔
232
    @boundscheck checkbounds(Bool, a, i...) || return false
381,909✔
233
    ii = _sub2ind(size(a), i...)
381,889✔
234
    return @inbounds isassigned(memoryrefnew(a.ref, ii, false))
381,889✔
235
end
236

237
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
92✔
238
    @inline
21,576,469✔
239
    @_noub_if_noinbounds_meta
21,576,469✔
240
    @boundscheck checkbounds(Bool, a, i) || return false
21,703,901✔
241
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
21,703,897✔
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
4,094✔
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))
7,488,708✔
261
    return dest
6,581,262✔
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)
6✔
275
    n == 0 && return dest
3,257,463✔
276
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
6,459,858✔
277
    return dest
3,229,932✔
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)
67,604✔
287
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
129✔
288
copyto!(dest::Memory, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
51,165,271✔
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)
4,378,931✔
292

293
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
62✔
294
    n == 0 && return dest
27,944,708✔
295
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
27,753,740✔
296
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
27,754,655✔
297
    @boundscheck checkbounds(src, soffs:soffs+n-1)
27,754,619✔
298
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
27,754,630✔
299
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
300
        unsafe_copyto!(dest, src, n)
54,498,376✔
301
    end
302
    return dest
26,743,819✔
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)))
4✔
310

311
_copyto2arg!(dest, src) = copyto!(dest, firstindex(dest), src, firstindex(src), length(src))
724,278✔
312

313
copyto!(dest::Array, src::Array) = _copyto2arg!(dest, src)
39,539✔
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)
684,597✔
319
copyto!(dest::Array{T}, src::Memory{T}) where {T} = _copyto2arg!(dest, src)
129✔
320
copyto!(dest::Memory{T}, src::Array{T}) where {T} = _copyto2arg!(dest, src)
13✔
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
6,304✔
357
    @inline
6,248,980✔
358
    xT = x isa T ? x : convert(T, x)::T
6,249,030✔
359
    return _fill!(A, xT)
1,780,430,723✔
360
end
361
function _fill!(A::AbstractArray{T}, x::T) where T
6,674✔
362
    for i in eachindex(A)
9,757,765✔
363
        A[i] = x
1,797,409,551✔
364
    end
2,147,483,647✔
365
    return A
6,370,266✔
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)
156,661✔
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
1,571,489✔
383
    ref = a.ref
2,172,788✔
384
    newmem = typeof(ref.mem)(undef, length(a))
2,172,788✔
385
    @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a))
3,898,083✔
386
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
2,172,788✔
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)
163✔
392
        setfield!(dst, :ref, getfield(src, :ref))
15✔
393
    end
394
    if getfield(dst, :size) !== getfield(src, :size)
163✔
395
        setfield!(dst, :size, getfield(src, :size))
160✔
396
    end
397
    return dst
163✔
398
end
399

400
## Constructors ##
401

402
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
124,378✔
403
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
4,288✔
404
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
10,224✔
405
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
12,200✔
406
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
18,054✔
407
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
3,213,645✔
408
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
458✔
409
similar(::Type{Array{T,N}}, dims::Dims) where {T,N} = similar(Array{T}, dims)
14,956,235✔
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
88,431✔
434
    @inline
5,530,533✔
435
    @_effect_free_terminates_locally_meta
5,530,533✔
436
    a = Vector{T}(undef, length(vals))
31,437,198✔
437
    if vals isa NTuple
5,530,533✔
438
        @_safeindex for i in 1:length(vals)
5,470,544✔
439
            a[i] = vals[i]
526,556✔
440
        end
511,030✔
441
    else
442
        # use afoldl to avoid type instability inside loop
443
        afoldl(1, vals...) do i, v
60,135✔
444
            @inbounds a[i] = v
127,391✔
445
            return i + 1
127,391✔
446
        end
447
    end
448
    return a
5,530,573✔
449
end
450

451
function getindex(::Type{Any}, @nospecialize vals...)
613,850✔
452
    @_effect_free_terminates_locally_meta
664,277✔
453
    a = Vector{Any}(undef, length(vals))
678,423✔
454
    @_safeindex for i = 1:length(vals)
1,050,890✔
455
        a[i] = vals[i]
1,801,714✔
456
    end
2,900,583✔
457
    return a
665,295✔
458
end
459
getindex(::Type{Any}) = Vector{Any}()
25,608,811✔
460

461
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
12✔
462
    ref = a.ref
93,907✔
463
    t = @_gc_preserve_begin ref
93,907✔
464
    p = unsafe_convert(Ptr{Cvoid}, ref)
93,907✔
465
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a) % UInt)
93,910✔
466
    @_gc_preserve_end t
93,904✔
467
    return a
18,189✔
468
end
469

470
to_dim(d::Integer) = d
×
471
to_dim(d::OneTo) = last(d)
212✔
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)
25,748,914✔
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)
25,748,966✔
574
fill(v, dims::NTuple{N, DimOrInd}) where {N} = (a=similar(Array{typeof(v),N}, dims); fill!(a, v); a)
14✔
575
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
180✔
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)
216,213✔
622
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
858,980,397✔
623
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
221,994✔
624
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,264✔
625
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
12,119✔
626
            a = Array{T,N}(undef, dims)
1,260,751✔
627
            fill!(a, $felt(T))
1,284,605,730✔
628
            return a
1,184,923✔
629
        end
630
        function $fname(::Type{T}, dims::Tuple{}) where {T}
631
            a = Array{T}(undef)
20✔
632
            fill!(a, $felt(T))
20✔
633
            return a
20✔
634
        end
635
        function $fname(::Type{T}, dims::NTuple{N, DimOrInd}) where {T,N}
636
            a = similar(Array{T,N}, dims)
1,654✔
637
            fill!(a, $felt(T))
3,708✔
638
            return a
1,654✔
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
56,870✔
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)
98✔
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)
55,918✔
653
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
8,162✔
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))
364,085✔
673

674
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
6,465✔
675
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
676
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
357,592✔
677
    a = Vector{T}()
357,601✔
678
    for x in itr
515,873✔
679
        push!(a, x)
240,182✔
680
    end
322,133✔
681
    return a
357,601✔
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
117✔
688
_similar_shape(itr, ::HasLength) = length(itr)::Integer
735,628✔
689
_similar_shape(itr, ::HasShape) = axes(itr)
14,751,528✔
690

691
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
213,040✔
692
    similar(c, T, 0)
693
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
74,870✔
694
    similar(c, T, len)
695
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
194,014✔
696
    similar(c, T, axs)
697

698
# make a collection appropriate for collecting `itr::Generator`
699
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
117✔
700
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
638,257✔
701
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
11,862,256✔
702

703
# used by syntax lowering for simple typed comprehensions
704
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
14,359,287✔
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))
784,781✔
760

761
collect(A::AbstractArray) = _collect_indices(axes(A), A)
144,419✔
762

763
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
261,258✔
764

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

768
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
212,930✔
769
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
212,983✔
770
    for x in itr
424,880✔
771
        push!(a,x)
7,505,224✔
772
    end
13,189,205✔
773
    return a
212,982✔
774
end
775

776
function _collect_indices(::Tuple{}, A)
777
    dest = Array{eltype(A),0}(undef)
26✔
778
    isempty(A) && return dest
26✔
779
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
26✔
780
end
781
function _collect_indices(indsA::Tuple{Vararg{OneTo}}, A)
7,513✔
782
    dest = Array{eltype(A)}(undef, length.(indsA))
98,222✔
783
    isempty(A) && return dest
98,223✔
784
    return copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(A), A)
98,209✔
785
end
786
function _collect_indices(indsA, A)
36✔
787
    B = Array{eltype(A)}(undef, length.(indsA))
121✔
788
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
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
1,301,799✔
813
            T = ($I).f
12,783✔
814
        else
815
            T = Base._return_type(_iterator_upper_bound, Tuple{typeof($I)})
1,289,016✔
816
        end
817
        promote_typejoin_union(T)
1,301,806✔
818
    end
819
end
820

821
function collect(itr::Generator)
518,011✔
822
    isz = IteratorSize(itr.iter)
978,754✔
823
    et = @default_eltype(itr)
824
    if isa(isz, SizeUnknown)
978,754✔
825
        return grow_to!(Vector{et}(), itr)
112,591✔
826
    else
827
        shp = _similar_shape(itr, isz)
866,993✔
828
        y = iterate(itr)
1,372,164✔
829
        if y === nothing
866,187✔
830
            return _array_for(et, isz, shp)
759✔
831
        end
832
        v1, st = y
865,428✔
833
        dest = _array_for(typeof(v1), isz, shp)
865,618✔
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
865,428✔
837
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
865,612✔
838
        collect_to_with_first!(dest, v1, itr, st)::RT
10,855,432✔
839
    end
840
end
841

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

845
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
106,379✔
846
    et = @default_eltype(itr)
132,378✔
847
    shp = _similar_shape(itr, isz)
192,744✔
848
    y = iterate(itr)
384,192✔
849
    if y === nothing
192,739✔
850
        return _similar_for(c, et, itr, isz, shp)
1,209✔
851
    end
852
    v1, st = y
131,168✔
853
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
191,597✔
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
131,168✔
857
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
131,223✔
858
    collect_to_with_first!(dest, v1, itr, st)::RT
191,530✔
859
end
860

861
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
103,485✔
862
    i1 = first(LinearIndices(dest))
996,598✔
863
    dest[i1] = v1
1,056,474✔
864
    return collect_to!(dest, itr, i1+1, st)
11,343,444✔
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
1,636✔
873
    @inline
1,819✔
874
    new = similar(dest, promote_typejoin(T, typeof(el)))
1,819✔
875
    f = first(LinearIndices(dest))
1,819✔
876
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
3,631✔
877
    @inbounds new[i] = el
1,819✔
878
    return new
1,819✔
879
end
880

881
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
501,246✔
882
    # collect to dest array, checking the type of each result. if a result does not
883
    # match, widen the result type and re-dispatch.
884
    i = offs
998,417✔
885
    while true
95,378,624✔
886
        y = iterate(itr, st)
189,697,798✔
887
        y === nothing && break
95,378,615✔
888
        el, st = y
94,025,184✔
889
        if el isa T
94,025,184✔
890
            @inbounds dest[i] = el
94,320,331✔
891
            i += 1
94,320,331✔
892
        else
893
            new = setindex_widen_up_to(dest, el, i)
1,819✔
894
            return collect_to!(new, itr, i+1, st)
1,819✔
895
        end
896
    end
94,320,331✔
897
    return dest
1,056,465✔
898
end
899

900
function grow_to!(dest, itr)
1,531✔
901
    y = iterate(itr)
113,225✔
902
    y === nothing && return dest
112,630✔
903
    dest2 = empty(dest, typeof(y[1]))
628✔
904
    push!(dest2, y[1])
721✔
905
    grow_to!(dest2, itr, y[2])
620✔
906
end
907

908
function push_widen(dest, el)
52✔
909
    @inline
55✔
910
    new = sizehint!(empty(dest, promote_typejoin(eltype(dest), typeof(el))), length(dest))
56✔
911
    if new isa AbstractSet
55✔
912
        # TODO: merge back these two branches when copy! is re-enabled for sets/vectors
913
        union!(new, dest)
1✔
914
    else
915
        append!(new, dest)
108✔
916
    end
917
    push!(new, el)
55✔
918
    return new
55✔
919
end
920

921
function grow_to!(dest, itr, st)
666✔
922
    T = eltype(dest)
681✔
923
    y = iterate(itr, st)
1,171✔
924
    while y !== nothing
4,162✔
925
        el, st = y
3,536✔
926
        if el isa T
3,536✔
927
            push!(dest, el)
3,484✔
928
        else
929
            new = push_widen(dest, el)
58✔
930
            return grow_to!(new, itr, st)
55✔
931
        end
932
        y = iterate(itr, st)
4,609✔
933
    end
3,481✔
934
    return dest
626✔
935
end
936

937
## Indexing: getindex ##
938

939
"""
940
    getindex(collection, key...)
941

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

945
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
946

947
# Examples
948
```jldoctest; filter = r"^\\s+\\S+\\s+=>\\s+\\d\$"m
949
julia> A = Dict("a" => 1, "b" => 2)
950
Dict{String, Int64} with 2 entries:
951
  "b" => 2
952
  "a" => 1
953

954
julia> getindex(A, "a")
955
1
956
```
957
"""
958
function getindex end
959

960
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
56,307✔
961
    @inline
144,175,862✔
962
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
189,834,174✔
963
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
189,835,951✔
964
end
965

966
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
967
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
21,810✔
968
    @inline
830,055✔
969
    @boundscheck checkbounds(A, I)
2,907,138✔
970
    lI = length(I)
2,907,136✔
971
    X = similar(A, axes(I))
2,907,147✔
972
    if lI > 0
2,907,136✔
973
        copyto!(X, firstindex(X), A, first(I), lI)
3,306,102✔
974
    end
975
    return X
2,902,428✔
976
end
977

978
# getindex for carrying out logical indexing for AbstractUnitRange{Bool} as Bool <: Integer
979
getindex(a::Array, r::AbstractUnitRange{Bool}) = getindex(a, to_index(r))
21✔
980

981
function getindex(A::Array, c::Colon)
4,455✔
982
    lI = length(A)
15,292✔
983
    X = similar(A, lI)
15,292✔
984
    if lI > 0
15,292✔
985
        unsafe_copyto!(X, 1, A, 1, lI)
30,580✔
986
    end
987
    return X
15,292✔
988
end
989

990
# This is redundant with the abstract fallbacks, but needed for bootstrap
991
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
3,170,023✔
992
    return S[ A[i] for i in I ]
3,170,263✔
993
end
994

995
## Indexing: setindex! ##
996

997
"""
998
    setindex!(collection, value, key...)
999

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

1003
# Examples
1004
```jldoctest; filter = r"^\\s+\\S+\\s+=>\\s+\\d\$"m
1005
julia> a = Dict("a"=>1)
1006
Dict{String, Int64} with 1 entry:
1007
  "a" => 1
1008

1009
julia> setindex!(a, 2, "b")
1010
Dict{String, Int64} with 2 entries:
1011
  "b" => 2
1012
  "a" => 1
1013
```
1014
"""
1015
function setindex! end
1016

1017
function setindex!(A::Array{T}, x, i::Int) where {T}
3,311,890✔
1018
    @_propagate_inbounds_meta
1,744,442,059✔
1019
    x = x isa T ? x : convert(T, x)::T
1,749,086,922✔
1020
    return _setindex!(A, x, i)
2,147,483,647✔
1021
end
1022
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
6,813✔
1023
    @_noub_if_noinbounds_meta
1,740,714,806✔
1024
    @boundscheck checkbounds(Bool, A, i) || throw_boundserror(A, (i,))
2,147,483,647✔
1025
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
2,147,483,647✔
1026
    return A
2,147,483,647✔
1027
end
1028
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
845,648✔
1029
    @_propagate_inbounds_meta
61,468,301✔
1030
    x = x isa T ? x : convert(T, x)::T
61,472,168✔
1031
    return _setindex!(A, x, i1, i2, I...)
78,309,561✔
1032
end
1033
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
4✔
1034
    @inline
60,419,526✔
1035
    @_noub_if_noinbounds_meta
60,419,526✔
1036
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
78,314,433✔
1037
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
78,314,415✔
1038
    return A
77,347,727✔
1039
end
1040

1041
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
78,294,998✔
1042
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
80,505,105✔
1043
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
24,852,278✔
1044
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
75,667,581✔
1045
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
1046
    __safe_setindex!(A, convert(T, x)::T, i))
36,462✔
1047

1048
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1049
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
97✔
1050
    @_propagate_inbounds_meta
814,972✔
1051
    @boundscheck setindex_shape_check(X, length(I))
832,914✔
1052
    @boundscheck checkbounds(A, I)
832,914✔
1053
    require_one_based_indexing(X)
814,972✔
1054
    X′ = unalias(A, X)
815,461✔
1055
    I′ = unalias(A, I)
814,973✔
1056
    count = 1
814,972✔
1057
    for i in I′
851,942✔
1058
        @inbounds A[i] = X′[count]
5,932,407✔
1059
        count += 1
5,932,407✔
1060
    end
11,078,091✔
1061
    return A
828,939✔
1062
end
1063

1064
# Faster contiguous setindex! with copyto!
1065
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
120✔
1066
    @inline
1,013,140✔
1067
    @boundscheck checkbounds(A, I)
1,013,211✔
1068
    lI = length(I)
1,013,211✔
1069
    @boundscheck setindex_shape_check(X, lI)
1,013,211✔
1070
    if lI > 0
1,013,211✔
1071
        unsafe_copyto!(A, first(I), X, 1, lI)
2,025,814✔
1072
    end
1073
    return A
1,013,182✔
1074
end
1075
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
44✔
1076
    @inline
74✔
1077
    lI = length(A)
74✔
1078
    @boundscheck setindex_shape_check(X, lI)
74✔
1079
    if lI > 0
74✔
1080
        unsafe_copyto!(A, 1, X, 1, lI)
148✔
1081
    end
1082
    return A
74✔
1083
end
1084

1085
# Pick new memory size for efficiently growing an array
1086
# TODO: This should know about the size of our GC pools
1087
# Specifically we are wasting ~10% of memory for small arrays
1088
# by not picking memory sizes that max out a GC pool
1089
function overallocation(maxsize)
484✔
1090
    # compute maxsize = maxsize + 3*maxsize^(7/8) + maxsize/8
1091
    # for small n, we grow faster than O(n)
1092
    # for large n, we grow at O(n/8)
1093
    # and as we reach O(memory) for memory>>1MB,
1094
    # this means we end by adding about 10% of memory each time
1095
    # most commonly, this will take steps of 0-3-9-34 or 1-4-16-66 or 2-8-33
1096
    exp2 = sizeof(maxsize) * 8 - Core.Intrinsics.ctlz_int(maxsize)
11,792,436✔
1097
    maxsize += (1 << div(exp2 * 7, 8)) * 3 + div(maxsize, 8)
11,792,436✔
1098
    return maxsize
11,711,861✔
1099
end
1100

1101
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
11,546,826✔
1102

1103
function _growbeg_internal!(a::Vector, delta::Int, len::Int)
140,536✔
1104
    @_terminates_locally_meta
140,536✔
1105
    ref = a.ref
140,536✔
1106
    mem = ref.mem
140,536✔
1107
    offset = memoryrefoffset(ref)
140,536✔
1108
    newlen = len + delta
140,536✔
1109
    memlen = length(mem)
140,536✔
1110
    if offset + len - 1 > memlen || offset < 1
281,072✔
1111
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1112
    end
1113
    # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1114
    # the +1 is because I didn't want to have an off by 1 error.
1115
    newmemlen = max(overallocation(len), len + 2 * delta + 1)
140,536✔
1116
    newoffset = div(newmemlen - newlen, 2) + 1
140,536✔
1117
    # If there is extra data after the end of the array we can use that space so long as there is enough
1118
    # space at the end that there won't be quadratic behavior with a mix of growth from both ends.
1119
    # Specifically, we want to ensure that we will only do this operation once before
1120
    # increasing the size of the array, and that we leave enough space at both the beginning and the end.
1121
    if newoffset + newlen < memlen
140,536✔
1122
        newoffset = div(memlen - newlen, 2) + 1
1,990✔
1123
        newmem = mem
1,990✔
1124
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
2,682✔
1125
        for j in offset:newoffset+delta-1
2,639✔
1126
            @inbounds _unsetindex!(mem, j)
26,704✔
1127
        end
42,586✔
1128
    else
1129
        newmem = array_new_memory(mem, newmemlen)
138,546✔
1130
        unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
138,546✔
1131
    end
1132
    if ref !== a.ref
140,536✔
1133
        throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1134
    end
1135
    setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
140,536✔
1136
end
1137

1138
function _growbeg!(a::Vector, delta::Integer)
19✔
1139
    @_noub_meta
4,229,801✔
1140
    delta = Int(delta)
4,229,801✔
1141
    delta == 0 && return # avoid attempting to index off the end
4,238,351✔
1142
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
4,238,043✔
1143
    ref = a.ref
4,515,404✔
1144
    len = length(a)
4,515,404✔
1145
    offset = memoryrefoffset(ref)
4,515,404✔
1146
    newlen = len + delta
4,515,404✔
1147
    # if offset is far enough advanced to fit data in existing memory without copying
1148
    if delta <= offset - 1
4,515,404✔
1149
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
4,366,266✔
1150
        setfield!(a, :size, (newlen,))
4,366,266✔
1151
    else
1152
        @noinline _growbeg_internal!(a, delta, len)
149,138✔
1153
        setfield!(a, :size, (newlen,))
149,138✔
1154
    end
1155
    return
4,515,397✔
1156
end
1157

1158
function _growend_internal!(a::Vector, delta::Int, len::Int)
10,906,078✔
1159
    ref = a.ref
10,906,078✔
1160
    mem = ref.mem
10,906,078✔
1161
    memlen = length(mem)
10,906,078✔
1162
    newlen = len + delta
10,906,078✔
1163
    offset = memoryrefoffset(ref)
10,906,078✔
1164
    newmemlen = offset + newlen - 1
10,906,078✔
1165
    if offset + len - 1 > memlen || offset < 1
21,812,156✔
1166
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1167
    end
1168

1169
    if offset - 1 > div(5 * newlen, 4)
10,906,078✔
1170
        # If the offset is far enough that we can copy without resizing
1171
        # while maintaining proportional spacing on both ends of the array
1172
        # note that this branch prevents infinite growth when doing combinations
1173
        # of push! and popfirst! (i.e. when using a Vector as a queue)
1174
        newmem = mem
342✔
1175
        newoffset = div(newlen, 8) + 1
342✔
1176
    else
1177
        # grow either by our computed overallocation factor
1178
        # or exactly the requested size, whichever is larger
1179
        # TODO we should possibly increase the offset if the current offset is nonzero.
1180
        newmemlen2 = max(overallocation(memlen), newmemlen)
10,905,736✔
1181
        newmem = array_new_memory(mem, newmemlen2)
10,906,890✔
1182
        newoffset = offset
10,905,736✔
1183
    end
1184
    newref = @inbounds memoryref(newmem, newoffset)
10,906,078✔
1185
    unsafe_copyto!(newref, ref, len)
13,289,698✔
1186
    if ref !== a.ref
10,906,078✔
1187
        @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1188
    end
1189
    setfield!(a, :ref, newref)
10,906,078✔
1190
return
10,906,078✔
1191
end
1192

1193
function _growend!(a::Vector, delta::Integer)
739✔
1194
    @_noub_meta
110,757,020✔
1195
    delta = Int(delta)
110,757,020✔
1196
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
110,880,489✔
1197
    ref = a.ref
154,107,116✔
1198
    mem = ref.mem
154,107,116✔
1199
    memlen = length(mem)
154,107,116✔
1200
    len = length(a)
154,107,116✔
1201
    newlen = len + delta
154,107,116✔
1202
    offset = memoryrefoffset(ref)
154,107,116✔
1203
    newmemlen = offset + newlen - 1
154,107,116✔
1204
    if memlen < newmemlen
154,107,116✔
1205
        @noinline _growend_internal!(a, delta, len)
13,101,772✔
1206
    end
1207
    setfield!(a, :size, (newlen,))
154,107,116✔
1208
    return
154,053,724✔
1209
end
1210

1211
function _growat!(a::Vector, i::Integer, delta::Integer)
583,331✔
1212
    @_terminates_globally_noub_meta
583,332✔
1213
    delta = Int(delta)
583,332✔
1214
    i = Int(i)
583,332✔
1215
    i == 1 && return _growbeg!(a, delta)
583,332✔
1216
    len = length(a)
439,620✔
1217
    i == len + 1 && return _growend!(a, delta)
439,620✔
1218
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
377,268✔
1219
    1 < i <= len || throw(BoundsError(a, i))
377,270✔
1220
    ref = a.ref
377,266✔
1221
    mem = ref.mem
377,266✔
1222
    memlen = length(mem)
377,266✔
1223
    newlen = len + delta
377,266✔
1224
    offset = memoryrefoffset(ref)
377,266✔
1225
    newmemlen = offset + newlen - 1
377,266✔
1226

1227
    # which side would we rather grow into?
1228
    prefer_start = i <= div(len, 2)
377,266✔
1229
    # if offset is far enough advanced to fit data in beginning of the memory
1230
    if prefer_start && delta <= offset - 1
377,266✔
1231
        newref = @inbounds memoryref(mem, offset - delta)
113,109✔
1232
        unsafe_copyto!(newref, ref, i)
226,218✔
1233
        setfield!(a, :ref, newref)
113,109✔
1234
        setfield!(a, :size, (newlen,))
113,109✔
1235
        for j in i:i+delta-1
153,637✔
1236
            @inbounds _unsetindex!(a, j)
135,861✔
1237
        end
129,199✔
1238
    elseif !prefer_start && memlen >= newmemlen
264,157✔
1239
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
405,480✔
1240
        setfield!(a, :size, (newlen,))
202,740✔
1241
        for j in i:i+delta-1
245,099✔
1242
            @inbounds _unsetindex!(a, j)
228,208✔
1243
        end
218,963✔
1244
    else
1245
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1246
        # the +1 is because I didn't want to have an off by 1 error.
1247
        newmemlen = max(overallocation(memlen), len+2*delta+1)
61,417✔
1248
        newoffset = (newmemlen - newlen) ÷ 2 + 1
61,417✔
1249
        newmem = array_new_memory(mem, newmemlen)
61,417✔
1250
        newref = @inbounds memoryref(newmem, newoffset)
61,417✔
1251
        unsafe_copyto!(newref, ref, i-1)
122,834✔
1252
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
122,834✔
1253
        setfield!(a, :ref, newref)
61,417✔
1254
        setfield!(a, :size, (newlen,))
61,417✔
1255
    end
1256
end
1257

1258
# efficiently delete part of an array
1259
function _deletebeg!(a::Vector, delta::Integer)
52,399✔
1260
    delta = Int(delta)
5,237,838✔
1261
    len = length(a)
5,509,997✔
1262
    # See comment in _deleteend!
1263
    if unsigned(delta) > unsigned(len)
5,509,997✔
1264
        throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
×
1265
    end
1266
    for i in 1:delta
5,287,821✔
1267
        @inbounds _unsetindex!(a, i)
13,037,332✔
1268
    end
20,100,816✔
1269
    newlen = len - delta
5,509,997✔
1270
    setfield!(a, :size, (newlen,))
5,509,997✔
1271
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
5,509,997✔
1272
        newref = @inbounds memoryref(a.ref, delta + 1)
5,434,516✔
1273
        setfield!(a, :ref, newref)
5,434,516✔
1274
    end
1275
    return
5,509,997✔
1276
end
1277
function _deleteend!(a::Vector, delta::Integer)
128✔
1278
    delta = Int(delta)
5,339,172✔
1279
    len = length(a)
10,372,147✔
1280
    # Do the comparison unsigned, to so the compiler knows `len` cannot be negative.
1281
    # This works because if delta is negative, it will overflow and still trigger.
1282
    # This enables the compiler to skip the check sometimes.
1283
    if unsigned(delta) > unsigned(len)
10,372,147✔
1284
        throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
×
1285
    end
1286
    newlen = len - delta
10,372,147✔
1287
    for i in newlen+1:len
15,436,843✔
1288
        @inbounds _unsetindex!(a, i)
130,434,887✔
1289
    end
250,203,701✔
1290
    setfield!(a, :size, (newlen,))
10,372,147✔
1291
    return
10,372,142✔
1292
end
1293
function _deleteat!(a::Vector, i::Integer, delta::Integer)
157,315✔
1294
    i = Int(i)
157,315✔
1295
    len = length(a)
157,315✔
1296
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
157,315✔
1297
    1 <= i <= len || throw(BoundsError(a, i))
157,315✔
1298
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
157,315✔
1299
    newa = a
157,315✔
1300
    if 2*i + delta <= len
157,315✔
1301
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
88,981✔
1302
        _deletebeg!(a, delta)
7,466,574✔
1303
    else
1304
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
198,238✔
1305
        _deleteend!(a, delta)
111,199✔
1306
    end
1307
    return
157,315✔
1308
end
1309
## Dequeue functionality ##
1310

1311
"""
1312
    push!(collection, items...) -> collection
1313

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

1317
# Examples
1318
```jldoctest
1319
julia> push!([1, 2, 3], 4, 5, 6)
1320
6-element Vector{Int64}:
1321
 1
1322
 2
1323
 3
1324
 4
1325
 5
1326
 6
1327
```
1328

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

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

1335
See also [`pushfirst!`](@ref).
1336
"""
1337
function push! end
1338

1339
function push!(a::Vector{T}, item) where T
28,576✔
1340
    @inline
28,147,935✔
1341
    # convert first so we don't grow the array if the assignment won't work
1342
    # and also to avoid a dynamic dynamic dispatch in the common case that
1343
    # `item` is poorly-typed and `a` is well-typed
1344
    item = item isa T ? item : convert(T, item)::T
28,169,472✔
1345
    return _push!(a, item)
70,845,473✔
1346
end
1347
function _push!(a::Vector{T}, item::T) where T
669✔
1348
    _growend!(a, 1)
70,845,471✔
1349
    @_safeindex a[length(a)] = item
70,845,471✔
1350
    return a
70,823,218✔
1351
end
1352

1353
# specialize and optimize the single argument case
1354
function push!(a::Vector{Any}, @nospecialize x)
525✔
1355
    _growend!(a, 1)
78,353,137✔
1356
    @_safeindex a[length(a)] = x
78,353,137✔
1357
    return a
78,353,131✔
1358
end
1359
function push!(a::Vector{Any}, @nospecialize x...)
17✔
1360
    @_terminates_locally_meta
31✔
1361
    na = length(a)
31✔
1362
    nx = length(x)
31✔
1363
    _growend!(a, nx)
31✔
1364
    @_safeindex for i = 1:nx
31✔
1365
        a[na+i] = x[i]
119✔
1366
    end
207✔
1367
    return a
31✔
1368
end
1369

1370
"""
1371
    append!(collection, collections...) -> collection.
1372

1373
For an ordered container `collection`, add the elements of each `collections`
1374
to the end of it.
1375

1376
!!! compat "Julia 1.6"
1377
    Specifying multiple collections to be appended requires at least Julia 1.6.
1378

1379
# Examples
1380
```jldoctest
1381
julia> append!([1], [2, 3])
1382
3-element Vector{Int64}:
1383
 1
1384
 2
1385
 3
1386

1387
julia> append!([1, 2, 3], [4, 5], [6])
1388
6-element Vector{Int64}:
1389
 1
1390
 2
1391
 3
1392
 4
1393
 5
1394
 6
1395
```
1396

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

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

1403
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1404
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1405
"""
1406
function append! end
1407

1408
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
10,226✔
1409
    items isa Tuple && (items = map(x -> convert(T, x), items))
2,444,656✔
1410
    n = Int(length(items))::Int
980,333✔
1411
    _growend!(a, n)
983,409✔
1412
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
1,038,327✔
1413
    return a
983,406✔
1414
end
1415

1416
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
127,437✔
1417
push!(a::AbstractVector, iter...) = append!(a, iter)
741,734✔
1418
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
19✔
1419

1420
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
81,863✔
1421
    n = Int(length(iter))::Int
83,215✔
1422
    sizehint!(a, length(a) + n; shrink=false)
81,876✔
1423
    for item in iter
104,226✔
1424
        push!(a, item)
37,967✔
1425
    end
46,717✔
1426
    a
81,859✔
1427
end
1428
function _append!(a::AbstractVector, ::IteratorSize, iter)
45,547✔
1429
    for item in iter
63,859✔
1430
        push!(a, item)
28,426✔
1431
    end
28,538✔
1432
    a
45,548✔
1433
end
1434

1435
"""
1436
    prepend!(a::Vector, collections...) -> collection
1437

1438
Insert the elements of each `collections` to the beginning of `a`.
1439

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

1443
!!! compat "Julia 1.6"
1444
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1445

1446
# Examples
1447
```jldoctest
1448
julia> prepend!([3], [1, 2])
1449
3-element Vector{Int64}:
1450
 1
1451
 2
1452
 3
1453

1454
julia> prepend!([6], [1, 2], [3, 4, 5])
1455
6-element Vector{Int64}:
1456
 1
1457
 2
1458
 3
1459
 4
1460
 5
1461
 6
1462
```
1463
"""
1464
function prepend! end
1465

1466
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
2,153✔
1467
    items isa Tuple && (items = map(x -> convert(T, x), items))
1,965✔
1468
    n = length(items)
4,040✔
1469
    _growbeg!(a, n)
7,771✔
1470
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1471
    # just the last n elements instead of all of them from the first
1472
    copyto!(a, 1, items, lastindex(items)-n+1, n)
7,765✔
1473
    return a
4,040✔
1474
end
1475

1476
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
231✔
1477
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
16✔
1478
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
7✔
1479

1480
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
211✔
1481
    @_terminates_locally_meta
212✔
1482
    require_one_based_indexing(a)
212✔
1483
    n = Int(length(iter))::Int
212✔
1484
    sizehint!(a, length(a) + n; first=true, shrink=false)
212✔
1485
    n = 0
212✔
1486
    for item in iter
213✔
1487
        n += 1
373✔
1488
        pushfirst!(a, item)
374✔
1489
    end
369✔
1490
    reverse!(a, 1, n)
206✔
1491
    a
206✔
1492
end
1493
function _prepend!(a::Vector, ::IteratorSize, iter)
3✔
1494
    n = 0
3✔
1495
    for item in iter
5✔
1496
        n += 1
8✔
1497
        pushfirst!(a, item)
11✔
1498
    end
13✔
1499
    reverse!(a, 1, n)
2✔
1500
    a
2✔
1501
end
1502

1503
"""
1504
    resize!(a::Vector, n::Integer) -> a
1505

1506
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1507
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1508
guaranteed to be initialized.
1509

1510
# Examples
1511
```jldoctest
1512
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1513
3-element Vector{Int64}:
1514
 6
1515
 5
1516
 4
1517

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

1520
julia> length(a)
1521
8
1522

1523
julia> a[1:6]
1524
6-element Vector{Int64}:
1525
 6
1526
 5
1527
 4
1528
 3
1529
 2
1530
 1
1531
```
1532
"""
1533
function resize!(a::Vector, nl_::Integer)
549,152✔
1534
    nl = Int(nl_)::Int
10,144,586✔
1535
    l = length(a)
10,146,623✔
1536
    if nl > l
10,146,623✔
1537
        # Since l is positive, if nl > l, both are positive, and so nl-l is also
1538
        # positive. But the compiler does not know that, so we mask out top bit.
1539
        # This allows the compiler to skip the check
1540
        _growend!(a, (nl-l) & typemax(Int))
3,186,914✔
1541
    elseif nl != l
6,959,709✔
1542
        if nl < 0
1,332,365✔
1543
            _throw_argerror("new length must be ≥ 0")
×
1544
        end
1545
        _deleteend!(a, l-nl)
1,332,365✔
1546
    end
1547
    return a
10,146,623✔
1548
end
1549

1550
"""
1551
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1552

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

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

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

1566
See also [`resize!`](@ref).
1567

1568
# Notes on the performance model
1569

1570
For types that support `sizehint!`,
1571

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

1576
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1577
   `Base`.
1578

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

1581
!!! compat "Julia 1.11"
1582
    The `shrink` and `first` arguments were added in Julia 1.11.
1583
"""
1584
function sizehint! end
1585

1586
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
1,081,178✔
1587
    len = length(a)
533,067✔
1588
    ref = a.ref
533,067✔
1589
    mem = ref.mem
533,067✔
1590
    memlen = length(mem)
533,067✔
1591
    sz = max(Int(sz), len)
533,067✔
1592
    inc = sz - len
533,067✔
1593
    if sz <= memlen
533,067✔
1594
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1595
        if !shrink || memlen - sz <= div(memlen, 8)
963,981✔
1596
            return a
76,621✔
1597
        end
1598
        newmem = array_new_memory(mem, sz)
444,669✔
1599
        if first
443,476✔
1600
            newref = memoryref(newmem, inc + 1)
×
1601
        else
1602
            newref = memoryref(newmem)
443,476✔
1603
        end
1604
        unsafe_copyto!(newref, ref, len)
446,047✔
1605
        setfield!(a, :ref, newref)
443,476✔
1606
    elseif first
12,970✔
1607
        _growbeg!(a, inc)
×
1608
        newref = getfield(a, :ref)
×
1609
        newref = memoryref(newref, inc + 1)
×
1610
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
×
1611
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
×
1612
    else # last
1613
        _growend!(a, inc)
12,970✔
1614
        setfield!(a, :size, (len,)) # undo the size change from _growend!
12,970✔
1615
    end
1616
    a
456,446✔
1617
end
1618

1619
# Fall-back implementation for non-shrinkable collections
1620
# avoid defining this the normal way to avoid avoid infinite recursion
1621
function Core.kwcall(kwargs::NamedTuple{names}, ::typeof(sizehint!), a, sz) where names
2✔
1622
    get(kwargs, :first, false)::Bool
11,773✔
1623
    get(kwargs, :shrink, true)::Bool
11,773✔
1624
    isempty(diff_names(names, (:first, :shrink))) || kwerr(kwargs, sizehint!, a, sz)
11,773✔
1625
    sizehint!(a, sz)
11,773✔
1626
end
1627

1628
"""
1629
    pop!(collection) -> item
1630

1631
Remove an item in `collection` and return it. If `collection` is an
1632
ordered container, the last item is returned; for unordered containers,
1633
an arbitrary element is returned.
1634

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

1637
# Examples
1638
```jldoctest
1639
julia> A=[1, 2, 3]
1640
3-element Vector{Int64}:
1641
 1
1642
 2
1643
 3
1644

1645
julia> pop!(A)
1646
3
1647

1648
julia> A
1649
2-element Vector{Int64}:
1650
 1
1651
 2
1652

1653
julia> S = Set([1, 2])
1654
Set{Int64} with 2 elements:
1655
  2
1656
  1
1657

1658
julia> pop!(S)
1659
2
1660

1661
julia> S
1662
Set{Int64} with 1 element:
1663
  1
1664

1665
julia> pop!(Dict(1=>2))
1666
1 => 2
1667
```
1668
"""
1669
function pop!(a::Vector)
48,372✔
1670
    if isempty(a)
8,526,849✔
1671
        _throw_argerror("array must be non-empty")
×
1672
    end
1673
    item = a[end]
8,526,849✔
1674
    _deleteend!(a, 1)
8,526,849✔
1675
    return item
8,526,844✔
1676
end
1677

1678
"""
1679
    popat!(a::Vector, i::Integer, [default])
1680

1681
Remove the item at the given `i` and return it. Subsequent items
1682
are shifted to fill the resulting gap.
1683
When `i` is not a valid index for `a`, return `default`, or throw an error if
1684
`default` is not specified.
1685

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

1688
!!! compat "Julia 1.5"
1689
    This function is available as of Julia 1.5.
1690

1691
# Examples
1692
```jldoctest
1693
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1694
3
1695

1696
julia> a
1697
3-element Vector{Int64}:
1698
 4
1699
 2
1700
 1
1701

1702
julia> popat!(a, 4, missing)
1703
missing
1704

1705
julia> popat!(a, 4)
1706
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1707
[...]
1708
```
1709
"""
1710
function popat!(a::Vector, i::Integer)
4✔
1711
    @_propagate_inbounds_meta
5✔
1712
    x = a[i]
8✔
1713
    _deleteat!(a, i, 1)
2✔
1714
    x
2✔
1715
end
1716

1717
function popat!(a::Vector, i::Integer, default)
2✔
1718
    if 1 <= i <= length(a)
2✔
1719
        x = @inbounds a[i]
1✔
1720
        _deleteat!(a, i, 1)
1✔
1721
        x
1✔
1722
    else
1723
        default
1✔
1724
    end
1725
end
1726

1727
"""
1728
    pushfirst!(collection, items...) -> collection
1729

1730
Insert one or more `items` at the beginning of `collection`.
1731

1732
This function is called `unshift` in many other programming languages.
1733

1734
# Examples
1735
```jldoctest
1736
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1737
6-element Vector{Int64}:
1738
 5
1739
 6
1740
 1
1741
 2
1742
 3
1743
 4
1744
```
1745
"""
1746
function pushfirst!(a::Vector{T}, item) where T
336✔
1747
    @inline
4,006,923✔
1748
    item = item isa T ? item : convert(T, item)::T
4,006,926✔
1749
    return _pushfirst!(a, item)
4,015,303✔
1750
end
UNCOV
1751
function _pushfirst!(a::Vector{T}, item::T) where T
×
1752
    _growbeg!(a, 1)
4,015,791✔
1753
    @_safeindex a[1] = item
4,012,171✔
1754
    return a
4,012,171✔
1755
end
1756

1757
# specialize and optimize the single argument case
1758
function pushfirst!(a::Vector{Any}, @nospecialize x)
58✔
1759
    _growbeg!(a, 1)
360,411✔
1760
    @_safeindex a[1] = x
355,730✔
1761
    return a
355,730✔
1762
end
1763
function pushfirst!(a::Vector{Any}, @nospecialize x...)
2✔
1764
    @_terminates_locally_meta
2✔
1765
    nx = length(x)
2✔
1766
    _growbeg!(a, nx)
4✔
1767
    @_safeindex for i = 1:nx
2✔
1768
        a[i] = x[i]
6✔
1769
    end
10✔
1770
    return a
2✔
1771
end
1772

1773
"""
1774
    popfirst!(collection) -> item
1775

1776
Remove the first `item` from `collection`.
1777

1778
This function is called `shift` in many other programming languages.
1779

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

1782
# Examples
1783
```jldoctest
1784
julia> A = [1, 2, 3, 4, 5, 6]
1785
6-element Vector{Int64}:
1786
 1
1787
 2
1788
 3
1789
 4
1790
 5
1791
 6
1792

1793
julia> popfirst!(A)
1794
1
1795

1796
julia> A
1797
5-element Vector{Int64}:
1798
 2
1799
 3
1800
 4
1801
 5
1802
 6
1803
```
1804
"""
1805
function popfirst!(a::Vector)
593✔
1806
    if isempty(a)
5,480,802✔
1807
        _throw_argerror("array must be non-empty")
×
1808
    end
1809
    item = a[1]
5,480,802✔
1810
    _deletebeg!(a, 1)
5,480,802✔
1811
    return item
5,480,802✔
1812
end
1813

1814
"""
1815
    insert!(a::Vector, index::Integer, item)
1816

1817
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1818
the resulting `a`.
1819

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

1822
# Examples
1823
```jldoctest
1824
julia> insert!(Any[1:6;], 3, "here")
1825
7-element Vector{Any}:
1826
 1
1827
 2
1828
  "here"
1829
 3
1830
 4
1831
 5
1832
 6
1833
```
1834
"""
1835
function insert!(a::Array{T,1}, i::Integer, item) where T
328✔
1836
    @_propagate_inbounds_meta
534,195✔
1837
    item = item isa T ? item : convert(T, item)::T
534,202✔
1838
    return _insert!(a, i, item)
590,830✔
1839
end
1840
function _insert!(a::Array{T,1}, i::Integer, item::T) where T
1841
    @_noub_meta
534,161✔
1842
    # Throw convert error before changing the shape of the array
1843
    _growat!(a, i, 1)
590,830✔
1844
    # :noub, because _growat! already did bound check
1845
    @inbounds a[i] = item
590,828✔
1846
    return a
590,828✔
1847
end
1848

1849
"""
1850
    deleteat!(a::Vector, i::Integer)
1851

1852
Remove the item at the given `i` and return the modified `a`. Subsequent items
1853
are shifted to fill the resulting gap.
1854

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

1857
# Examples
1858
```jldoctest
1859
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1860
5-element Vector{Int64}:
1861
 6
1862
 4
1863
 3
1864
 2
1865
 1
1866
```
1867
"""
1868
function deleteat!(a::Vector, i::Integer)
269✔
1869
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
38,921✔
1870
    _deleteat!(a, i, 1)
39,410✔
1871
    return a
38,921✔
1872
end
1873

1874
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
34,091✔
1875
    if eltype(r) === Bool
109,741✔
1876
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1877
    else
1878
        f = first(r)
109,741✔
1879
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
109,735✔
1880
        isempty(r) || _deleteat!(a, f, length(r))
215,963✔
1881
        return a
109,874✔
1882
    end
1883
end
1884

1885
"""
1886
    deleteat!(a::Vector, inds)
1887

1888
Remove the items at the indices given by `inds`, and return the modified `a`.
1889
Subsequent items are shifted to fill the resulting gap.
1890

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

1894
# Examples
1895
```jldoctest
1896
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1897
3-element Vector{Int64}:
1898
 5
1899
 3
1900
 1
1901

1902
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1903
3-element Vector{Int64}:
1904
 5
1905
 3
1906
 1
1907

1908
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1909
ERROR: ArgumentError: indices must be unique and sorted
1910
Stacktrace:
1911
[...]
1912
```
1913
"""
1914
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1915
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
36,270✔
1916

1917
struct Nowhere; end
77✔
1918
push!(::Nowhere, _) = nothing
1,491,201✔
1919
_growend!(::Nowhere, _) = nothing
×
1920

1921
function _push_deleted!(dltd, a::Vector, ind)
1922
    @_propagate_inbounds_meta
1,491,203✔
1923
    if isassigned(a, ind)
1,491,203✔
1924
        push!(dltd, a[ind])
1,491,215✔
1925
    else
1926
        _growend!(dltd, 1)
×
1927
    end
1928
end
1929

1930
function _copy_item!(a::Vector, p, q)
1931
    @_propagate_inbounds_meta
4,379,673✔
1932
    if isassigned(a, q)
4,379,673✔
1933
        a[p] = a[q]
4,379,673✔
1934
    else
1935
        _unsetindex!(a, p)
×
1936
    end
1937
end
1938

1939
function _deleteat!(a::Vector, inds, dltd=Nowhere())
35,786✔
1940
    n = length(a)
72,075✔
1941
    y = iterate(inds)
35,796✔
1942
    y === nothing && return a
35,786✔
1943
    (p, s) = y
35,480✔
1944
    checkbounds(a, p)
35,484✔
1945
    @inbounds _push_deleted!(dltd, a, p)
35,480✔
1946
    q = p+1
35,476✔
1947
    while true
1,491,203✔
1948
        y = iterate(inds, s)
1,491,214✔
1949
        y === nothing && break
1,491,203✔
1950
        (i,s) = y
1,455,729✔
1951
        if !(q <= i <= n)
1,455,729✔
1952
            if i < q
2✔
1953
                _throw_argerror("indices must be unique and sorted")
1✔
1954
            else
1955
                throw(BoundsError())
1✔
1956
            end
1957
        end
1958
        while q < i
2,878,348✔
1959
            @inbounds _copy_item!(a, p, q)
1,422,621✔
1960
            p += 1; q += 1
1,422,621✔
1961
        end
1,422,621✔
1962
        @inbounds _push_deleted!(dltd, a, i)
1,455,735✔
1963
        q = i+1
1,455,727✔
1964
    end
1,455,727✔
1965
    while q <= n
2,950,332✔
1966
        @inbounds _copy_item!(a, p, q)
2,914,858✔
1967
        p += 1; q += 1
2,914,858✔
1968
    end
2,914,858✔
1969
    _deleteend!(a, n-p+1)
1,491,201✔
1970
    return a
35,474✔
1971
end
1972

1973
# Simpler and more efficient version for logical indexing
1974
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1975
    n = length(a)
4,029✔
1976
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1977
    p = 1
4,024✔
1978
    for (q, i) in enumerate(inds)
8,047✔
1979
        @inbounds _copy_item!(a, p, q)
42,194✔
1980
        p += !i
42,194✔
1981
    end
80,365✔
1982
    _deleteend!(a, n-p+1)
21,353✔
1983
    return a
4,024✔
1984
end
1985

1986
const _default_splice = []
1987

1988
"""
1989
    splice!(a::Vector, index::Integer, [replacement]) -> item
1990

1991
Remove the item at the given index, and return the removed item.
1992
Subsequent items are shifted left to fill the resulting gap.
1993
If specified, replacement values from an ordered
1994
collection will be spliced in place of the removed item.
1995

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

1998
# Examples
1999
```jldoctest
2000
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
2001
2
2002

2003
julia> A
2004
5-element Vector{Int64}:
2005
 6
2006
 5
2007
 4
2008
 3
2009
 1
2010

2011
julia> splice!(A, 5, -1)
2012
1
2013

2014
julia> A
2015
5-element Vector{Int64}:
2016
  6
2017
  5
2018
  4
2019
  3
2020
 -1
2021

2022
julia> splice!(A, 1, [-1, -2, -3])
2023
6
2024

2025
julia> A
2026
7-element Vector{Int64}:
2027
 -1
2028
 -2
2029
 -3
2030
  5
2031
  4
2032
  3
2033
 -1
2034
```
2035

2036
To insert `replacement` before an index `n` without removing any items, use
2037
`splice!(collection, n:n-1, replacement)`.
2038
"""
2039
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,692✔
2040
    v = a[i]
3,708✔
2041
    m = length(ins)
3,416✔
2042
    if m == 0
3,416✔
2043
        _deleteat!(a, i, 1)
541✔
2044
    elseif m == 1
2,875✔
2045
        a[i] = only(ins)
267✔
2046
    else
2047
        _growat!(a, i, m-1)
2,608✔
2048
        k = 1
2,608✔
2049
        for x in ins
2,608✔
2050
            a[i+k-1] = x
333,511✔
2051
            k += 1
333,511✔
2052
        end
333,511✔
2053
    end
2054
    return v
3,416✔
2055
end
2056

2057
"""
2058
    splice!(a::Vector, indices, [replacement]) -> items
2059

2060
Remove items at specified indices, and return a collection containing
2061
the removed items.
2062
Subsequent items are shifted left to fill the resulting gaps.
2063
If specified, replacement values from an ordered collection will be spliced in
2064
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
2065

2066
To insert `replacement` before an index `n` without removing any items, use
2067
`splice!(collection, n:n-1, replacement)`.
2068

2069
$(_DOCS_ALIASING_WARNING)
2070

2071
!!! compat "Julia 1.5"
2072
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
2073

2074
!!! compat "Julia 1.8"
2075
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
2076

2077
# Examples
2078
```jldoctest
2079
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
2080
Int64[]
2081

2082
julia> A
2083
8-element Vector{Int64}:
2084
 -1
2085
 -2
2086
 -3
2087
  2
2088
  5
2089
  4
2090
  3
2091
 -1
2092
```
2093
"""
2094
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
150,038✔
2095
    v = a[r]
220,268✔
2096
    m = length(ins)
116,100✔
2097
    if m == 0
116,100✔
2098
        deleteat!(a, r)
74,059✔
2099
        return v
37,090✔
2100
    end
2101

2102
    n = length(a)
79,010✔
2103
    f = first(r)
79,010✔
2104
    l = last(r)
79,010✔
2105
    d = length(r)
79,010✔
2106

2107
    if m < d
79,010✔
2108
        delta = d - m
12,726✔
2109
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
19,194✔
2110
    elseif m > d
66,284✔
2111
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
66,178✔
2112
    end
2113

2114
    k = 1
79,010✔
2115
    for x in ins
90,516✔
2116
        a[f+k-1] = x
4,150,393✔
2117
        k += 1
4,150,393✔
2118
    end
5,533,820✔
2119
    return v
79,010✔
2120
end
2121

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

2124
function empty!(a::Vector)
158✔
2125
    _deleteend!(a, length(a))
549,248✔
2126
    return a
434,612✔
2127
end
2128

2129
# use memcmp for cmp on byte arrays
UNCOV
2130
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
×
UNCOV
2131
    aref = a.ref
×
UNCOV
2132
    bref = b.ref
×
UNCOV
2133
    ta = @_gc_preserve_begin aref
×
UNCOV
2134
    tb = @_gc_preserve_begin bref
×
UNCOV
2135
    pa = unsafe_convert(Ptr{Cvoid}, aref)
×
UNCOV
2136
    pb = unsafe_convert(Ptr{Cvoid}, bref)
×
UNCOV
2137
    c = memcmp(pa, pb, min(length(a),length(b)))
×
UNCOV
2138
    @_gc_preserve_end ta
×
UNCOV
2139
    @_gc_preserve_end tb
×
UNCOV
2140
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
×
2141
end
2142

2143
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
2144
# use memcmp for == on bit integer types
2145
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,536✔
2146
    if size(a) == size(b)
4,628✔
2147
        aref = a.ref
2,345✔
2148
        bref = b.ref
2,345✔
2149
        ta = @_gc_preserve_begin aref
2,345✔
2150
        tb = @_gc_preserve_begin bref
2,345✔
2151
        pa = unsafe_convert(Ptr{Cvoid}, aref)
2,345✔
2152
        pb = unsafe_convert(Ptr{Cvoid}, bref)
2,345✔
2153
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
2,345✔
2154
        @_gc_preserve_end ta
2,345✔
2155
        @_gc_preserve_end tb
2,345✔
2156
        return c == 0
2,345✔
2157
    else
2158
        return false
×
2159
    end
2160
end
2161

2162
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
83✔
2163
    len = length(a)
9,178✔
2164
    if len == length(b)
9,178✔
2165
        aref = a.ref
9,016✔
2166
        bref = b.ref
9,016✔
2167
        ta = @_gc_preserve_begin aref
9,016✔
2168
        tb = @_gc_preserve_begin bref
9,016✔
2169
        T = eltype(Arr)
85✔
2170
        pa = unsafe_convert(Ptr{T}, aref)
9,016✔
2171
        pb = unsafe_convert(Ptr{T}, bref)
9,016✔
2172
        c = memcmp(pa, pb, sizeof(T) * len)
9,016✔
2173
        @_gc_preserve_end ta
9,016✔
2174
        @_gc_preserve_end tb
9,016✔
2175
        return c == 0
9,016✔
2176
    else
2177
        return false
162✔
2178
    end
2179
end
2180

2181
"""
2182
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2183

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

2187
# Examples
2188
```jldoctest
2189
julia> A = Vector(1:5)
2190
5-element Vector{Int64}:
2191
 1
2192
 2
2193
 3
2194
 4
2195
 5
2196

2197
julia> reverse(A)
2198
5-element Vector{Int64}:
2199
 5
2200
 4
2201
 3
2202
 2
2203
 1
2204

2205
julia> reverse(A, 1, 4)
2206
5-element Vector{Int64}:
2207
 4
2208
 3
2209
 2
2210
 1
2211
 5
2212

2213
julia> reverse(A, 3, 5)
2214
5-element Vector{Int64}:
2215
 1
2216
 2
2217
 5
2218
 4
2219
 3
2220
```
2221
"""
2222
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
3,567✔
2223
    s, n = Int(start), Int(stop)
3,567✔
2224
    B = similar(A)
3,567✔
2225
    for i = firstindex(A):s-1
3,568✔
2226
        B[i] = A[i]
1,677✔
2227
    end
3,066✔
2228
    for i = s:n
6,025✔
2229
        B[i] = A[n+s-i]
174,295✔
2230
    end
345,029✔
2231
    for i = n+1:lastindex(A)
4,392✔
2232
        B[i] = A[i]
1,680✔
2233
    end
3,072✔
2234
    return B
3,567✔
2235
end
2236

2237
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2238
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2239
    @eval begin
2240
        $f(A::AbstractVector; dims::D=:) where {D} = $_f(A, dims)
1,619,381✔
2241
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
13,094✔
2242
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2243
        function $_f(A::AbstractVector, dim::Integer)
2244
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
2245
            return $_f(A, :)
4✔
2246
        end
2247
    end
2248
end
2249

2250
function reverseind(a::AbstractVector, i::Integer)
3✔
2251
    li = LinearIndices(a)
3✔
2252
    first(li) + last(li) - i
3✔
2253
end
2254

2255
# This implementation of `midpoint` is performance-optimized but safe
2256
# only if `lo <= hi`.
2257
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
311,509✔
2258
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2259

2260
"""
2261
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2262

2263
In-place version of [`reverse`](@ref).
2264

2265
# Examples
2266
```jldoctest
2267
julia> A = Vector(1:5)
2268
5-element Vector{Int64}:
2269
 1
2270
 2
2271
 3
2272
 4
2273
 5
2274

2275
julia> reverse!(A);
2276

2277
julia> A
2278
5-element Vector{Int64}:
2279
 5
2280
 4
2281
 3
2282
 2
2283
 1
2284
```
2285
"""
2286
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
1,502,905✔
2287
    s, n = Int(start), Int(stop)
3,888,007✔
2288
    if n > s # non-empty and non-trivial
1,502,902✔
2289
        liv = LinearIndices(v)
63,368✔
2290
        if !(first(liv) ≤ s ≤ last(liv))
63,368✔
2291
            throw(BoundsError(v, s))
2✔
2292
        elseif !(first(liv) ≤ n ≤ last(liv))
63,366✔
2293
            throw(BoundsError(v, n))
×
2294
        end
2295
        r = n
63,366✔
2296
        @inbounds for i in s:midpoint(s, n-1)
112,768✔
2297
            v[i], v[r] = v[r], v[i]
7,865,867✔
2298
            r -= 1
7,865,867✔
2299
        end
15,668,368✔
2300
    end
2301
    return v
1,502,900✔
2302
end
2303

2304
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2305

2306
vcat() = Vector{Any}()
12,355✔
2307
hcat() = Vector{Any}()
1✔
2308

2309
function hcat(V::Vector{T}...) where T
63✔
2310
    height = length(V[1])
570✔
2311
    for j = 2:length(V)
570✔
2312
        if length(V[j]) != height
636✔
2313
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2314
        end
2315
    end
733✔
2316
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
569✔
2317
end
2318
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2319

2320
function vcat(arrays::Vector{T}...) where T
35,861✔
2321
    n = 0
35,861✔
2322
    for a in arrays
35,861✔
2323
        n += length(a)
2,071,871✔
2324
    end
2,107,695✔
2325
    arr = Vector{T}(undef, n)
35,861✔
2326
    nd = 1
35,861✔
2327
    for a in arrays
35,861✔
2328
        na = length(a)
2,071,871✔
2329
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,071,871✔
2330
        unsafe_copyto!(arr, nd, a, 1, na)
4,143,622✔
2331
        nd += na
2,071,871✔
2332
    end
2,107,695✔
2333
    return arr
35,861✔
2334
end
2335
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
36✔
2336

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

2339
## find ##
2340

2341
"""
2342
    findnext(A, i)
2343

2344
Find the next index after or including `i` of a `true` element of `A`,
2345
or `nothing` if not found.
2346

2347
Indices are of the same type as those returned by [`keys(A)`](@ref)
2348
and [`pairs(A)`](@ref).
2349

2350
# Examples
2351
```jldoctest
2352
julia> A = [false, false, true, false]
2353
4-element Vector{Bool}:
2354
 0
2355
 0
2356
 1
2357
 0
2358

2359
julia> findnext(A, 1)
2360
3
2361

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

2364
julia> A = [false false; true false]
2365
2×2 Matrix{Bool}:
2366
 0  0
2367
 1  0
2368

2369
julia> findnext(A, CartesianIndex(1, 1))
2370
CartesianIndex(2, 1)
2371
```
2372
"""
2373
findnext(A, start) = findnext(identity, A, start)
77,423✔
2374

2375
"""
2376
    findfirst(A)
2377

2378
Return the index or key of the first `true` value in `A`.
2379
Return `nothing` if no such value is found.
2380
To search for other kinds of values, pass a predicate as the first argument.
2381

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

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

2387
# Examples
2388
```jldoctest
2389
julia> A = [false, false, true, false]
2390
4-element Vector{Bool}:
2391
 0
2392
 0
2393
 1
2394
 0
2395

2396
julia> findfirst(A)
2397
3
2398

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

2401
julia> A = [false false; true false]
2402
2×2 Matrix{Bool}:
2403
 0  0
2404
 1  0
2405

2406
julia> findfirst(A)
2407
CartesianIndex(2, 1)
2408
```
2409
"""
2410
findfirst(A) = findfirst(identity, A)
2✔
2411

2412
# Needed for bootstrap, and allows defining only an optimized findnext method
2413
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
47,128✔
2414

2415
"""
2416
    findnext(predicate::Function, A, i)
2417

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

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

2426
# Examples
2427
```jldoctest
2428
julia> A = [1, 4, 2, 2];
2429

2430
julia> findnext(isodd, A, 1)
2431
1
2432

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

2435
julia> A = [1 4; 2 2];
2436

2437
julia> findnext(isodd, A, CartesianIndex(1, 1))
2438
CartesianIndex(1, 1)
2439

2440
julia> findnext(isspace, "a b c", 3)
2441
4
2442
```
2443
"""
2444
function findnext(testf::Function, A, start)
5,922✔
2445
    i = oftype(first(keys(A)), start)
133,182✔
2446
    l = last(keys(A))
194,142✔
2447
    i > l && return nothing
194,142✔
2448
    while true
654,592✔
2449
        testf(A[i]) && return i
656,472✔
2450
        i == l && break
605,777✔
2451
        # nextind(A, l) can throw/overflow
2452
        i = nextind(A, i)
582,759✔
2453
    end
582,740✔
2454
    return nothing
23,013✔
2455
end
2456

2457
"""
2458
    findfirst(predicate::Function, A)
2459

2460
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2461
Return `nothing` if there is no such element.
2462

2463
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2464
and [`pairs(A)`](@ref).
2465

2466
# Examples
2467
```jldoctest
2468
julia> A = [1, 4, 2, 2]
2469
4-element Vector{Int64}:
2470
 1
2471
 4
2472
 2
2473
 2
2474

2475
julia> findfirst(iseven, A)
2476
2
2477

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

2480
julia> findfirst(isequal(4), A)
2481
2
2482

2483
julia> A = [1 4; 2 2]
2484
2×2 Matrix{Int64}:
2485
 1  4
2486
 2  2
2487

2488
julia> findfirst(iseven, A)
2489
CartesianIndex(2, 1)
2490
```
2491
"""
2492
function findfirst(testf::Function, A)
14✔
2493
    for (i, a) in pairs(A)
21✔
2494
        testf(a) && return i
14✔
2495
    end
11✔
2496
    return nothing
7✔
2497
end
2498

2499
# Needed for bootstrap, and allows defining only an optimized findnext method
2500
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
3,149,255✔
2501
    findnext(testf, A, first(keys(A)))
2502

2503
findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::OneTo) where {T<:Integer} =
6✔
2504
    1 <= p.x <= r.stop ? convert(keytype(r), p.x) : nothing
2505

2506
findfirst(::typeof(iszero), ::OneTo) = nothing
2✔
2507
findfirst(::typeof(isone), r::OneTo) = isempty(r) ? nothing : oneunit(keytype(r))
5✔
2508

2509
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::AbstractUnitRange{<:Integer}) where {T<:Integer}
6✔
2510
    first(r) <= p.x <= last(r) || return nothing
29✔
2511
    i1 = first(keys(r))
9✔
2512
    return i1 + oftype(i1, p.x - first(r))
9✔
2513
end
2514

2515
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
151✔
2516
    isempty(r) && return nothing
151✔
2517
    minimum(r) <= p.x <= maximum(r) || return nothing
192✔
2518
    d = p.x - first(r)
106✔
2519
    iszero(d % step(r)) || return nothing
142✔
2520
    return convert(keytype(r), d ÷ step(r) + 1)
70✔
2521
end
2522

2523
findfirst(::typeof(iszero), r::AbstractRange) = findfirst(==(zero(first(r))), r)
130✔
2524
findfirst(::typeof(isone), r::AbstractRange) = findfirst(==(one(first(r))), r)
3✔
2525

2526
"""
2527
    findprev(A, i)
2528

2529
Find the previous index before or including `i` of a `true` element of `A`,
2530
or `nothing` if not found.
2531

2532
Indices are of the same type as those returned by [`keys(A)`](@ref)
2533
and [`pairs(A)`](@ref).
2534

2535
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2536

2537
# Examples
2538
```jldoctest
2539
julia> A = [false, false, true, true]
2540
4-element Vector{Bool}:
2541
 0
2542
 0
2543
 1
2544
 1
2545

2546
julia> findprev(A, 3)
2547
3
2548

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

2551
julia> A = [false false; true true]
2552
2×2 Matrix{Bool}:
2553
 0  0
2554
 1  1
2555

2556
julia> findprev(A, CartesianIndex(2, 1))
2557
CartesianIndex(2, 1)
2558
```
2559
"""
2560
findprev(A, start) = findprev(identity, A, start)
8,326✔
2561

2562
"""
2563
    findlast(A)
2564

2565
Return the index or key of the last `true` value in `A`.
2566
Return `nothing` if there is no `true` value in `A`.
2567

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

2571
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2572

2573
# Examples
2574
```jldoctest
2575
julia> A = [true, false, true, false]
2576
4-element Vector{Bool}:
2577
 1
2578
 0
2579
 1
2580
 0
2581

2582
julia> findlast(A)
2583
3
2584

2585
julia> A = falses(2,2);
2586

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

2589
julia> A = [true false; true false]
2590
2×2 Matrix{Bool}:
2591
 1  0
2592
 1  0
2593

2594
julia> findlast(A)
2595
CartesianIndex(2, 1)
2596
```
2597
"""
2598
findlast(A) = findlast(identity, A)
24✔
2599

2600
# Needed for bootstrap, and allows defining only an optimized findprev method
2601
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
7✔
2602

2603
"""
2604
    findprev(predicate::Function, A, i)
2605

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

2611
Indices are of the same type as those returned by [`keys(A)`](@ref)
2612
and [`pairs(A)`](@ref).
2613

2614
# Examples
2615
```jldoctest
2616
julia> A = [4, 6, 1, 2]
2617
4-element Vector{Int64}:
2618
 4
2619
 6
2620
 1
2621
 2
2622

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

2625
julia> findprev(isodd, A, 3)
2626
3
2627

2628
julia> A = [4 6; 1 2]
2629
2×2 Matrix{Int64}:
2630
 4  6
2631
 1  2
2632

2633
julia> findprev(isodd, A, CartesianIndex(1, 2))
2634
CartesianIndex(2, 1)
2635

2636
julia> findprev(isspace, "a b c", 3)
2637
2
2638
```
2639
"""
2640
function findprev(testf::Function, A, start)
211✔
2641
    f = first(keys(A))
9,362✔
2642
    i = oftype(f, start)
9,373✔
2643
    i < f && return nothing
9,362✔
2644
    while true
153,115✔
2645
        testf(A[i]) && return i
153,119✔
2646
        i == f && break
143,917✔
2647
        # prevind(A, f) can throw/underflow
2648
        i = prevind(A, i)
143,781✔
2649
    end
143,753✔
2650
    return nothing
133✔
2651
end
2652

2653
"""
2654
    findlast(predicate::Function, A)
2655

2656
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2657
Return `nothing` if there is no such element.
2658

2659
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2660
and [`pairs(A)`](@ref).
2661

2662
# Examples
2663
```jldoctest
2664
julia> A = [1, 2, 3, 4]
2665
4-element Vector{Int64}:
2666
 1
2667
 2
2668
 3
2669
 4
2670

2671
julia> findlast(isodd, A)
2672
3
2673

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

2676
julia> A = [1 2; 3 4]
2677
2×2 Matrix{Int64}:
2678
 1  2
2679
 3  4
2680

2681
julia> findlast(isodd, A)
2682
CartesianIndex(2, 1)
2683
```
2684
"""
2685
function findlast(testf::Function, A)
3✔
2686
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2687
        testf(a) && return i
6✔
2688
    end
6✔
2689
    return nothing
2✔
2690
end
2691

2692
# Needed for bootstrap, and allows defining only an optimized findprev method
2693
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
15,404✔
2694
    findprev(testf, A, last(keys(A)))
2695

2696
# for monotonic ranges, there is a unique index corresponding to a value, so findfirst and findlast are identical
2697
function findlast(p::Union{Fix2{typeof(isequal),<:Integer},Fix2{typeof(==),<:Integer},typeof(iszero),typeof(isone)},
13✔
2698
        r::AbstractUnitRange{<:Integer})
2699
    findfirst(p, r)
14✔
2700
end
2701

2702
function findlast(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T},typeof(iszero),typeof(isone)},
9✔
2703
        r::StepRange{T,S}) where {T,S}
2704
    findfirst(p, r)
9✔
2705
end
2706

2707
"""
2708
    findall(f::Function, A)
2709

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

2713
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2714
and [`pairs(A)`](@ref).
2715

2716
# Examples
2717
```jldoctest
2718
julia> x = [1, 3, 4]
2719
3-element Vector{Int64}:
2720
 1
2721
 3
2722
 4
2723

2724
julia> findall(isodd, x)
2725
2-element Vector{Int64}:
2726
 1
2727
 2
2728

2729
julia> A = [1 2 0; 3 4 0]
2730
2×3 Matrix{Int64}:
2731
 1  2  0
2732
 3  4  0
2733
julia> findall(isodd, A)
2734
2-element Vector{CartesianIndex{2}}:
2735
 CartesianIndex(1, 1)
2736
 CartesianIndex(2, 1)
2737

2738
julia> findall(!iszero, A)
2739
4-element Vector{CartesianIndex{2}}:
2740
 CartesianIndex(1, 1)
2741
 CartesianIndex(2, 1)
2742
 CartesianIndex(1, 2)
2743
 CartesianIndex(2, 2)
2744

2745
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2746
Dict{Symbol, Int64} with 3 entries:
2747
  :A => 10
2748
  :B => -1
2749
  :C => 0
2750

2751
julia> findall(≥(0), d)
2752
2-element Vector{Symbol}:
2753
 :A
2754
 :C
2755

2756
```
2757
"""
2758
function findall(testf::Function, A)
36✔
2759
    gen = (first(p) for p in pairs(A) if testf(last(p)))
43✔
2760
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
43✔
2761
end
2762

2763
# Broadcasting is much faster for small testf, and computing
2764
# integer indices from logical index using findall has a negligible cost
2765
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
339✔
2766

2767
"""
2768
    findall(A)
2769

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

2774
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2775
and [`pairs(A)`](@ref).
2776

2777
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2778

2779
# Examples
2780
```jldoctest
2781
julia> A = [true, false, false, true]
2782
4-element Vector{Bool}:
2783
 1
2784
 0
2785
 0
2786
 1
2787

2788
julia> findall(A)
2789
2-element Vector{Int64}:
2790
 1
2791
 4
2792

2793
julia> A = [true false; false true]
2794
2×2 Matrix{Bool}:
2795
 1  0
2796
 0  1
2797

2798
julia> findall(A)
2799
2-element Vector{CartesianIndex{2}}:
2800
 CartesianIndex(1, 1)
2801
 CartesianIndex(2, 2)
2802

2803
julia> findall(falses(3))
2804
Int64[]
2805
```
2806
"""
2807
function findall(A)
4✔
2808
    collect(first(p) for p in pairs(A) if last(p))
4✔
2809
end
2810

2811
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2812
function findall(A::AbstractArray{Bool})
34✔
2813
    n = count(A)
3,661✔
2814
    I = Vector{eltype(keys(A))}(undef, n)
3,656✔
2815
    cnt = 1
3,656✔
2816
    for (i,a) in pairs(A)
7,304✔
2817
        if a
206,078✔
2818
            I[cnt] = i
129,250✔
2819
            cnt += 1
129,250✔
2820
        end
2821
    end
408,505✔
2822
    I
3,656✔
2823
end
2824

2825
findall(x::Bool) = x ? [1] : Vector{Int}()
×
2826
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2827
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2828

2829
# similar to Matlab's ismember
2830
"""
2831
    indexin(a, b)
2832

2833
Return an array containing the first index in `b` for
2834
each value in `a` that is a member of `b`. The output
2835
array contains `nothing` wherever `a` is not a member of `b`.
2836

2837
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2838

2839
# Examples
2840
```jldoctest
2841
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2842

2843
julia> b = ['a', 'b', 'c'];
2844

2845
julia> indexin(a, b)
2846
6-element Vector{Union{Nothing, Int64}}:
2847
 1
2848
 2
2849
 3
2850
 2
2851
  nothing
2852
 1
2853

2854
julia> indexin(b, a)
2855
3-element Vector{Union{Nothing, Int64}}:
2856
 1
2857
 2
2858
 3
2859
```
2860
"""
2861
function indexin(a, b::AbstractArray)
7✔
2862
    inds = keys(b)
7✔
2863
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2864
    for (val, ind) in zip(b, inds)
14✔
2865
        get!(bdict, val, ind)
30✔
2866
    end
53✔
2867
    return Union{eltype(inds), Nothing}[
7✔
2868
        get(bdict, i, nothing) for i in a
2869
    ]
2870
end
2871

2872
function _findin(a::Union{AbstractArray, Tuple}, b::AbstractSet)
375✔
2873
    ind  = Vector{eltype(keys(a))}()
561✔
2874
    @inbounds for (i,ai) in pairs(a)
606✔
2875
        ai in b && push!(ind, i)
90,563✔
2876
    end
180,565✔
2877
    ind
375✔
2878
end
2879
_findin(a::Union{AbstractArray, Tuple}, b) = _findin(a, Set(b))
375✔
2880

2881
# If two collections are already sorted, _findin can be computed with
2882
# a single traversal of the two collections. This is much faster than
2883
# using a hash table (although it has the same complexity).
2884
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
9✔
2885
    viter, witer = keys(v), eachindex(w)
9✔
2886
    out  = eltype(viter)[]
9✔
2887
    vy, wy = iterate(viter), iterate(witer)
11✔
2888
    if vy === nothing || wy === nothing
17✔
2889
        return out
2✔
2890
    end
2891
    viteri, i = vy
7✔
2892
    witerj, j = wy
7✔
2893
    @inbounds begin
7✔
2894
        vi, wj = v[viteri], w[witerj]
7✔
2895
        while true
54✔
2896
            if isless(vi, wj)
56✔
2897
                vy = iterate(viter, i)
25✔
2898
                if vy === nothing
14✔
2899
                    break
2✔
2900
                end
2901
                viteri, i = vy
12✔
2902
                vi        = v[viteri]
12✔
2903
            elseif isless(wj, vi)
40✔
2904
                wy = iterate(witer, j)
44✔
2905
                if wy === nothing
24✔
2906
                    break
4✔
2907
                end
2908
                witerj, j = wy
20✔
2909
                wj        = w[witerj]
20✔
2910
            else
2911
                push!(out, viteri)
16✔
2912
                vy = iterate(viter, i)
25✔
2913
                if vy === nothing
16✔
2914
                    break
1✔
2915
                end
2916
                # We only increment the v iterator because v can have
2917
                # repeated matches to a single value in w
2918
                viteri, i = vy
15✔
2919
                vi        = v[viteri]
15✔
2920
            end
2921
        end
47✔
2922
    end
2923
    return out
7✔
2924
end
2925

2926
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2927
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2928
        return _sortedfindin(x, pred.x)
9✔
2929
    else
2930
        return _findin(x, pred.x)
6✔
2931
    end
2932
end
2933
# issorted fails for some element types so the method above has to be restricted
2934
# to element with isless/< defined.
2935
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
373✔
2936
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2937

2938
# Copying subregions
2939
function indcopy(sz::Dims, I::Vector)
1✔
2940
    n = length(I)
1✔
2941
    s = sz[n]
1✔
2942
    for i = n+1:length(sz)
2✔
2943
        s *= sz[i]
×
2944
    end
×
2945
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2946
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2947
    dst, src
1✔
2948
end
2949

2950
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2951
    n = length(I)
1✔
2952
    s = sz[n]
1✔
2953
    for i = n+1:length(sz)
1✔
2954
        s *= sz[i]
×
2955
    end
×
2956
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2957
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2958
    dst, src
1✔
2959
end
2960

2961
## Filter ##
2962

2963
"""
2964
    filter(f, a)
2965

2966
Return a copy of collection `a`, removing elements for which `f` is `false`.
2967
The function `f` is passed one argument.
2968

2969
!!! compat "Julia 1.4"
2970
    Support for `a` as a tuple requires at least Julia 1.4.
2971

2972
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2973

2974
# Examples
2975
```jldoctest
2976
julia> a = 1:10
2977
1:10
2978

2979
julia> filter(isodd, a)
2980
5-element Vector{Int64}:
2981
 1
2982
 3
2983
 5
2984
 7
2985
 9
2986
```
2987
"""
2988
function filter(f, a::Array{T, N}) where {T, N}
2,507✔
2989
    j = 1
2,507✔
2990
    b = Vector{T}(undef, length(a))
2,507✔
2991
    for ai in a
2,507✔
2992
        @inbounds b[j] = ai
183,306✔
2993
        j = ifelse(f(ai)::Bool, j+1, j)
184,473✔
2994
    end
183,306✔
2995
    resize!(b, j-1)
2,507✔
2996
    sizehint!(b, length(b))
2,507✔
2997
    b
2,507✔
2998
end
2999

3000
function filter(f, a::AbstractArray)
80✔
3001
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
80✔
3002

3003
    j = 1
80✔
3004
    idxs = Vector{Int}(undef, length(a))
83✔
3005
    for idx in eachindex(a)
83✔
3006
        @inbounds idxs[j] = idx
77,670✔
3007
        ai = @inbounds a[idx]
77,670✔
3008
        j = ifelse(f(ai)::Bool, j+1, j)
79,203✔
3009
    end
155,261✔
3010
    resize!(idxs, j-1)
79✔
3011
    res = a[idxs]
79✔
3012
    empty!(idxs)
3,167✔
3013
    sizehint!(idxs, 0)
79✔
3014
    return res
79✔
3015
end
3016

3017
"""
3018
    filter!(f, a)
3019

3020
Update collection `a`, removing elements for which `f` is `false`.
3021
The function `f` is passed one argument.
3022

3023
# Examples
3024
```jldoctest
3025
julia> filter!(isodd, Vector(1:10))
3026
5-element Vector{Int64}:
3027
 1
3028
 3
3029
 5
3030
 7
3031
 9
3032
```
3033
"""
3034
function filter!(f, a::AbstractVector)
753,610✔
3035
    j = firstindex(a)
753,923✔
3036
    for ai in a
753,924✔
3037
        @inbounds a[j] = ai
3,352,261✔
3038
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
3,540,719✔
3039
    end
3,352,270✔
3040
    j > lastindex(a) && return a
753,923✔
3041
    if a isa Vector
442,170✔
3042
        resize!(a, j-1)
442,169✔
3043
        sizehint!(a, j-1)
442,169✔
3044
    else
3045
        deleteat!(a, j:lastindex(a))
1✔
3046
    end
3047
    return a
442,170✔
3048
end
3049

3050
"""
3051
    filter(f)
3052

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

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

3059
# Examples
3060
```jldoctest
3061
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
3062
(1, 2, 4, 6)
3063

3064
julia> map(filter(iseven), [1:3, 2:4, 3:5])
3065
3-element Vector{Vector{Int64}}:
3066
 [2]
3067
 [2, 4]
3068
 [4]
3069
```
3070
!!! compat "Julia 1.9"
3071
    This method requires at least Julia 1.9.
3072
"""
3073
function filter(f)
1✔
3074
    Fix1(filter, f)
1✔
3075
end
3076

3077
"""
3078
    keepat!(a::Vector, inds)
3079
    keepat!(a::BitVector, inds)
3080

3081
Remove the items at all the indices which are not given by `inds`,
3082
and return the modified `a`.
3083
Items which are kept are shifted to fill the resulting gaps.
3084

3085
$(_DOCS_ALIASING_WARNING)
3086

3087
`inds` must be an iterator of sorted and unique integer indices.
3088
See also [`deleteat!`](@ref).
3089

3090
!!! compat "Julia 1.7"
3091
    This function is available as of Julia 1.7.
3092

3093
# Examples
3094
```jldoctest
3095
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
3096
3-element Vector{Int64}:
3097
 6
3098
 4
3099
 2
3100
```
3101
"""
3102
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
3103

3104
"""
3105
    keepat!(a::Vector, m::AbstractVector{Bool})
3106
    keepat!(a::BitVector, m::AbstractVector{Bool})
3107

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

3112
# Examples
3113
```jldoctest
3114
julia> a = [:a, :b, :c];
3115

3116
julia> keepat!(a, [true, false, true])
3117
2-element Vector{Symbol}:
3118
 :a
3119
 :c
3120

3121
julia> a
3122
2-element Vector{Symbol}:
3123
 :a
3124
 :c
3125
```
3126
"""
3127
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
154✔
3128

3129
# set-like operators for vectors
3130
# These are moderately efficient, preserve order, and remove dupes.
3131

3132
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
11,354✔
3133
    # P, U force specialization
3134
    if pred(x, state)
19,760✔
3135
        update!(state, x)
7,810✔
3136
        true
3137
    else
3138
        false
3139
    end
3140
end
3141

3142
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
290✔
3143
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
896✔
3144

3145
function _grow!(pred!, v::AbstractVector, itrs)
110✔
3146
    filter!(pred!, v) # uniquify v
317✔
3147
    for itr in itrs
317✔
3148
        mapfilter(pred!, push!, itr, v)
621✔
3149
    end
918✔
3150
    return v
317✔
3151
end
3152

3153
union!(v::AbstractVector{T}, itrs...) where {T} =
284✔
3154
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3155

3156
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
33✔
3157
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3158

3159
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
4✔
3160
    seen = Set{eltype(v)}()
6✔
3161
    filter!(_grow_filter!(seen), v)
6✔
3162
    shrinker!(seen, itrs...)
6✔
3163
    filter!(in(seen), v)
6✔
3164
end
3165

3166
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
3✔
3167
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
3✔
3168

3169
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
863✔
3170

3171
function intersect(itr, itrs...)
384✔
3172
    T = promote_eltype(itr, itrs...)
384✔
3173
    keep = intersect!(Set{T}(itr), itrs...)
384✔
3174
    vectorfilter(T, _shrink_filter!(keep), itr)
384✔
3175
end
3176

3177
function setdiff(itr, itrs...)
404✔
3178
    T = eltype(itr)
406✔
3179
    keep = setdiff!(Set{T}(itr), itrs...)
1,422✔
3180
    vectorfilter(T, _shrink_filter!(keep), itr)
406✔
3181
end
3182

3183
function intersect(v::AbstractVector, r::AbstractRange)
7✔
3184
    T = promote_eltype(v, r)
73✔
3185
    common = Iterators.filter(in(r), v)
73✔
3186
    seen = Set{T}(common)
73✔
3187
    return vectorfilter(T, _shrink_filter!(seen), common)
73✔
3188
end
3189
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
4✔
3190

3191
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3192
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
4,564✔
3193
    if i isa Bool # Not via dispatch to avoid ambiguities
480,660,101✔
3194
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
3195
    else
3196
        _getindex(v, i)
779,419,402✔
3197
    end
3198
end
3199

3200
"""
3201
    wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
3202

3203
Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version
3204
of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers.
3205
"""
3206
function wrap end
3207

3208
# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller
UNCOV
3209
function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N}
×
3210
    mem = ref.mem
47,661✔
3211
    mem_len = length(mem) + 1 - memoryrefoffset(ref)
47,661✔
3212
    len = Core.checked_dims(dims...)
47,500✔
3213
    @boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len)
47,664✔
3214
    return ref
47,497✔
3215
end
3216

3217
@noinline invalid_wrap_err(len, dims, proddims) = throw(DimensionMismatch(LazyString(
1✔
3218
    "Attempted to wrap a MemoryRef of length ", len, " with an Array of size dims=", dims,
3219
    " which is invalid because prod(dims) = ", proddims, " > ", len,
3220
    " so that the array would have more elements than the underlying memory can store.")))
3221

3222
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
4✔
3223
    dims = convert(Dims, dims)
4✔
3224
    ref = _wrap(m, dims)
4✔
3225
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
4✔
3226
end
3227

3228
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
3✔
3229
    dims = convert(Dims, dims)
3✔
3230
    ref = _wrap(memoryref(m), dims)
4✔
3231
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
2✔
3232
end
3233
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
4✔
3234
    dims = (Int(l),)
47,653✔
3235
    ref = _wrap(m, dims)
47,655✔
3236
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
47,490✔
3237
end
3238
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
1✔
3239
    dims = (Int(l),)
1✔
3240
    ref = _wrap(memoryref(m), (l,))
1✔
3241
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
1✔
3242
end
3243
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
108✔
3244
    ref = memoryref(m)
388,503✔
3245
    dims = (length(m),)
388,503✔
3246
    $(Expr(:new, :(Array{T, 1}), :ref, :dims))
371,544✔
3247
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