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

JuliaLang / julia / #38088

02 Jun 2025 02:05AM UTC coverage: 25.772% (+0.03%) from 25.739%
#38088

push

local

web-flow
Clarify documentation around `close`, `flush`, and `isopen` (#58020)

Co-authored-by: Max Horn <max@quendi.de>

12850 of 49861 relevant lines covered (25.77%)

713769.44 hits per line

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

60.07
/base/array.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
## array.jl: Dense arrays
4

5
"""
6
    DimensionMismatch([msg])
7

8
The objects called do not have matching dimensionality. Optional argument `msg` is a
9
descriptive error string.
10
"""
11
struct DimensionMismatch <: Exception
12
    msg::AbstractString
1✔
13
end
14
DimensionMismatch() = DimensionMismatch("")
×
15

16
## Type aliases for convenience ##
17
"""
18
    AbstractVector{T}
19

20
Supertype for one-dimensional arrays (or array-like types) with
21
elements of type `T`. Alias for [`AbstractArray{T,1}`](@ref).
22
"""
23
const AbstractVector{T} = AbstractArray{T,1}
24

25
"""
26
    AbstractMatrix{T}
27

28
Supertype for two-dimensional arrays (or array-like types) with
29
elements of type `T`. Alias for [`AbstractArray{T,2}`](@ref).
30
"""
31
const AbstractMatrix{T} = AbstractArray{T,2}
32

33
"""
34
    AbstractVecOrMat{T}
35

36
Union type of [`AbstractVector{T}`](@ref) and [`AbstractMatrix{T}`](@ref).
37
"""
38
const AbstractVecOrMat{T} = Union{AbstractVector{T}, AbstractMatrix{T}}
39
const RangeIndex = Union{<:BitInteger, AbstractRange{<:BitInteger}}
40
const DimOrInd = Union{Integer, AbstractUnitRange}
41
const IntOrInd = Union{Int, AbstractUnitRange}
42
const DimsOrInds{N} = NTuple{N,DimOrInd}
43
const NeedsShaping = Union{Tuple{Integer,Vararg{Integer}}, Tuple{OneTo,Vararg{OneTo}}}
44

45
"""
46
    Array{T,N} <: AbstractArray{T,N}
47

48
`N`-dimensional dense array with elements of type `T`.
49
"""
50
Array
51

52
"""
53
    Vector{T} <: AbstractVector{T}
54

55
One-dimensional dense array with elements of type `T`, often used to represent
56
a mathematical vector. Alias for [`Array{T,1}`](@ref).
57

58
See also [`empty`](@ref), [`similar`](@ref) and [`zero`](@ref) for creating vectors.
59
"""
60
const Vector{T} = Array{T,1}
61

62
"""
63
    Matrix{T} <: AbstractMatrix{T}
64

65
Two-dimensional dense array with elements of type `T`, often used to represent
66
a mathematical matrix. Alias for [`Array{T,2}`](@ref).
67

68
See also [`fill`](@ref), [`zeros`](@ref), [`undef`](@ref) and [`similar`](@ref)
69
for creating matrices.
70
"""
71
const Matrix{T} = Array{T,2}
72

73
"""
74
    VecOrMat{T}
75

76
Union type of [`Vector{T}`](@ref) and [`Matrix{T}`](@ref) which allows functions to accept either a Matrix or a Vector.
77

78
# Examples
79
```jldoctest
80
julia> Vector{Float64} <: VecOrMat{Float64}
81
true
82

83
julia> Matrix{Float64} <: VecOrMat{Float64}
84
true
85

86
julia> Array{Float64, 3} <: VecOrMat{Float64}
87
false
88
```
89
"""
90
const VecOrMat{T} = Union{Vector{T}, Matrix{T}}
91

92
"""
93
    DenseArray{T, N} <: AbstractArray{T,N}
94

95
`N`-dimensional dense array with elements of type `T`.
96
The elements of a dense array are stored contiguously in memory.
97
"""
98
DenseArray
99

100
"""
101
    DenseVector{T}
102

103
One-dimensional [`DenseArray`](@ref) with elements of type `T`. Alias for `DenseArray{T,1}`.
104
"""
105
const DenseVector{T} = DenseArray{T,1}
106

107
"""
108
    DenseMatrix{T}
109

110
Two-dimensional [`DenseArray`](@ref) with elements of type `T`. Alias for `DenseArray{T,2}`.
111
"""
112
const DenseMatrix{T} = DenseArray{T,2}
113

114
"""
115
    DenseVecOrMat{T}
116

117
Union type of [`DenseVector{T}`](@ref) and [`DenseMatrix{T}`](@ref).
118
"""
119
const DenseVecOrMat{T} = Union{DenseVector{T}, DenseMatrix{T}}
120

121
## Basic functions ##
122

123
"""
124
    @_safeindex
125

126
This internal macro converts:
127
- `getindex(xs::Tuple, i::Int)` -> `__safe_getindex(xs, i)`
128
- `setindex!(xs::Vector{T}, x, i::Int)` -> `__safe_setindex!(xs, x, i)`
129
to tell the compiler that indexing operations within the applied expression are always
130
inbounds and do not need to taint `:consistent` and `:nothrow`.
131
"""
132
macro _safeindex(ex)
133
    return esc(_safeindex(ex))
134
end
135
function _safeindex(ex)
×
136
    isa(ex, Expr) || return ex
×
137
    if ex.head === :(=)
×
138
        lhs = ex.args[1]
×
139
        if isa(lhs, Expr) && lhs.head === :ref # xs[i] = x
×
140
            rhs = ex.args[2]
×
141
            xs = lhs.args[1]
×
142
            args = Vector{Any}(undef, length(lhs.args)-1)
×
143
            for i = 2:length(lhs.args)
×
144
                args[i-1] = _safeindex(lhs.args[i])
×
145
            end
×
146
            return Expr(:call, GlobalRef(@__MODULE__, :__safe_setindex!), xs, _safeindex(rhs), args...)
×
147
        end
148
    elseif ex.head === :ref # xs[i]
×
149
        return Expr(:call, GlobalRef(@__MODULE__, :__safe_getindex), ex.args...)
×
150
    end
151
    args = Vector{Any}(undef, length(ex.args))
×
152
    for i = 1:length(ex.args)
×
153
        args[i] = _safeindex(ex.args[i])
×
154
    end
×
155
    return Expr(ex.head, args...)
×
156
end
157

158
vect() = Vector{Any}()
41,856✔
159
function vect(X::T...) where T
1,102✔
160
    @_terminates_locally_meta
3,326✔
161
    vec = Vector{T}(undef, length(X))
10,499✔
162
    @_safeindex for i = 1:length(X)
3,472✔
163
        vec[i] = X[i]
13,318✔
164
    end
9,037✔
165
    return vec
3,399✔
166
end
167

168
"""
169
    vect(X...)
170

171
Create a [`Vector`](@ref) with element type computed from the `promote_typeof` of the argument,
172
containing the argument list.
173

174
# Examples
175
```jldoctest
176
julia> a = Base.vect(UInt8(1), 2.5, 1//2)
177
3-element Vector{Float64}:
178
 1.0
179
 2.5
180
 0.5
181
```
182
"""
183
function vect(X...)
3✔
184
    T = promote_typeof(X...)
3✔
185
    return T[X...]
3✔
186
end
187

188
size(a::Array, d::Integer) = size(a, Int(d)::Int)
×
189
function size(a::Array, d::Int)
190
    d < 1 && error("arraysize: dimension out of range")
133✔
191
    sz = getfield(a, :size)
1,310✔
192
    return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
1,310✔
193
end
194
size(a::Array) = getfield(a, :size)
90,740,799✔
195

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

198
allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0))
565,936✔
199

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

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

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

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

216
function _unsetindex!(A::Array, i::Int)
3,004,524✔
217
    @inline
3,070,895✔
218
    @boundscheck checkbounds(A, i)
25,051,403✔
219
    @inbounds _unsetindex!(memoryref(A.ref, i))
25,608,060✔
220
    return A
13,187,188✔
221
end
222

223

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

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

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

245
function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
3,455,798✔
246
    @inline
3,398,341✔
247
    @_noub_if_noinbounds_meta
3,398,341✔
248
    @boundscheck checkbounds(Bool, a, i) || return false
31,385,607✔
249
    return @inbounds isassigned(memoryrefnew(a.ref, i, false))
31,385,610✔
250
end
251

252

253
## copy ##
254

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

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

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

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

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

278
The `unsafe` prefix on this function indicates that no validation is performed to ensure
279
that n is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
280
the same manner as C.
281
"""
282
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
4,608✔
283
    n == 0 && return dest
79,870✔
284
    unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
61,444✔
285
    return dest
31,476✔
286
end
287

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

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

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

301
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
93,917✔
302
    n == 0 && return dest
1,006,360✔
303
    n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
803,954✔
304
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
803,954✔
305
    @boundscheck checkbounds(src, soffs:soffs+n-1)
803,954✔
306
    @inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs),
803,954✔
307
                  src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
308
        unsafe_copyto!(dest, src, n)
804,673✔
309
    end
310
    return dest
78,890✔
311
end
312

313

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

319
_copyto2arg!(dest, src) = copyto!(dest, firstindex(dest), src, firstindex(src), length(src))
197,807✔
320

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

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

330
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
331
# for bootstrapping purposes.
332
function fill!(dest::Array{T}, x) where T
372,088✔
333
    @inline
3,027,439✔
334
    x = x isa T ? x : convert(T, x)::T
3,027,863✔
335
    return _fill!(dest, x)
129,965,470✔
336
end
337
function _fill!(dest::Array{T}, x::T) where T
372,086✔
338
    for i in eachindex(dest)
5,888,891✔
339
        @inbounds dest[i] = x
137,314,424✔
340
    end
261,592,015✔
341
    return dest
4,133,108✔
342
end
343

344
"""
345
    copy(x)
346

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

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

355
@eval function copy(a::Array)
500,146✔
356
    # `copy` only throws when the size exceeds the max allocation size,
357
    # but since we're copying an existing array, we're guaranteed that this will not happen.
358
    @_nothrow_meta
286,483✔
359
    ref = a.ref
3,032,007✔
360
    newmem = typeof(ref.mem)(undef, length(a))
3,032,007✔
361
    @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a))
4,850,662✔
362
    return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size)))
3,032,008✔
363
end
364

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

376
## Constructors ##
377

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

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

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

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

401
julia> getindex(Int8, 1, 2, 3)
402
3-element Vector{Int8}:
403
 1
404
 2
405
 3
406
```
407
"""
408
function getindex(::Type{T}, vals...) where T
8,107,748✔
409
    @inline
8,248,290✔
410
    @_effect_free_terminates_locally_meta
8,248,287✔
411
    a = Vector{T}(undef, length(vals))
13,659,776✔
412
    if vals isa NTuple
8,248,290✔
413
        @_safeindex for i in 1:length(vals)
8,247,822✔
414
            a[i] = vals[i]
580,762✔
415
        end
92,250✔
416
    else
417
        # use afoldl to avoid type instability inside loop
418
        afoldl(1, vals...) do i, v
473✔
419
            @inbounds a[i] = v
1,426✔
420
            return i + 1
1,426✔
421
        end
422
    end
423
    return a
8,248,319✔
424
end
425

426
function getindex(::Type{Any}, @nospecialize vals...)
480,840✔
427
    @_effect_free_terminates_locally_meta
19,010✔
428
    a = Vector{Any}(undef, length(vals))
512,240✔
429
    @_safeindex for i = 1:length(vals)
262,505✔
430
        a[i] = vals[i]
964,417✔
431
    end
1,100,339✔
432
    return a
483,457✔
433
end
434
getindex(::Type{Any}) = Vector{Any}()
451,899✔
435

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

618
## Conversions ##
619

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

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

624
## Constructors ##
625

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

630
## copying iterators to containers
631

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

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

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

649
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
×
650
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
651
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
237,111✔
652
    a = Vector{T}()
237,111✔
653
    for x in itr
237,129✔
654
        push!(a, x)
1,171,429✔
655
    end
1,171,445✔
656
    return a
237,111✔
657
end
658

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

662
_similar_shape(itr, ::SizeUnknown) = nothing
×
663
_similar_shape(itr, ::HasLength) = length(itr)::Integer
271,299✔
664
_similar_shape(itr, ::HasShape) = axes(itr)
3,341,022✔
665

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

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

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

681

682
"""
683
    collect(iterator)
684

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

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

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

697
# Examples
698

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

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

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

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

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

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

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

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

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

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

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

743
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
2,017✔
744
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
2,017✔
745
    for x in itr
4,026✔
746
        push!(a,x)
20,968✔
747
    end
39,834✔
748
    return a
2,017✔
749
end
750

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

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

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

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

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

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

829
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
27✔
830
    i1 = first(LinearIndices(dest))
869✔
831
    dest[i1] = v1
897✔
832
    return collect_to!(dest, itr, i1+1, st)
2,273✔
833
end
834

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

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

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

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

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

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

905
## Iteration ##
906

907
iterate(A::Array, i=1) = (@inline; (i - 1)%UInt < length(A)%UInt ? (@inbounds A[i], i + 1) : nothing)
205,428,323✔
908

909
## Indexing: getindex ##
910

911
"""
912
    getindex(collection, key...)
913

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

917
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
918

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

926
julia> getindex(A, "a")
927
1
928
```
929
"""
930
function getindex end
931

932
function getindex(A::Array, i1::Int, i2::Int, I::Int...)
×
933
    @inline
×
934
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
×
935
    return @inbounds A[_to_linear_index(A, i1, i2, I...)]
×
936
end
937

938
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
939
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
81,085✔
940
    @inline
81,156✔
941
    @boundscheck checkbounds(A, I)
943,740✔
942
    lI = length(I)
943,740✔
943
    X = similar(A, axes(I))
943,740✔
944
    if lI > 0
943,740✔
945
        copyto!(X, firstindex(X), A, first(I), lI)
882,883✔
946
    end
947
    return X
938,632✔
948
end
949

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

953
function getindex(A::Array, c::Colon)
200✔
954
    lI = length(A)
9,306✔
955
    X = similar(A, lI)
9,306✔
956
    if lI > 0
9,306✔
957
        unsafe_copyto!(X, 1, A, 1, lI)
18,412✔
958
    end
959
    return X
9,306✔
960
end
961

962
# This is redundant with the abstract fallbacks, but needed for bootstrap
963
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
964
    return S[ A[i] for i in I ]
×
965
end
966

967
## Indexing: setindex! ##
968

969
"""
970
    setindex!(collection, value, key...)
971

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

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

981
julia> setindex!(a, 2, "b")
982
Dict{String, Int64} with 2 entries:
983
  "b" => 2
984
  "a" => 1
985
```
986
"""
987
function setindex! end
988

989
function setindex!(A::Array{T}, x, i::Int) where {T}
56,509,612✔
990
    @_propagate_inbounds_meta
56,787,810✔
991
    x = x isa T ? x : convert(T, x)::T
60,636,507✔
992
    return _setindex!(A, x, i)
441,495,704✔
993
end
994
function _setindex!(A::Array{T}, x::T, i::Int) where {T}
56,508,178✔
995
    @_noub_if_noinbounds_meta
56,786,772✔
996
    @boundscheck (i - 1)%UInt < length(A)%UInt || throw_boundserror(A, (i,))
441,494,639✔
997
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false)
441,495,659✔
998
    return A
299,411,780✔
999
end
1000
function setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T}
×
1001
    @_propagate_inbounds_meta
×
1002
    x = x isa T ? x : convert(T, x)::T
×
1003
    return _setindex!(A, x, i1, i2, I...)
×
1004
end
1005
function _setindex!(A::Array{T}, x::T, i1::Int, i2::Int, I::Int...) where {T}
×
1006
    @inline
×
1007
    @_noub_if_noinbounds_meta
×
1008
    @boundscheck checkbounds(A, i1, i2, I...) # generally _to_linear_index requires bounds checking
×
1009
    memoryrefset!(memoryrefnew(A.ref, _to_linear_index(A, i1, i2, I...), false), x, :not_atomic, false)
×
1010
    return A
×
1011
end
1012

1013
__safe_setindex!(A::Vector{Any}, @nospecialize(x), i::Int) = (@inline; @_nothrow_noub_meta;
267,337✔
1014
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
2,949,727✔
1015
__safe_setindex!(A::Vector{T}, x::T, i::Int) where {T} = (@inline; @_nothrow_noub_meta;
10,666,216✔
1016
    memoryrefset!(memoryrefnew(A.ref, i, false), x, :not_atomic, false); return A)
23,522,733✔
1017
__safe_setindex!(A::Vector{T}, x,    i::Int) where {T} = (@inline;
×
1018
    __safe_setindex!(A, convert(T, x)::T, i))
×
1019

1020
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1021
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
68,685✔
1022
    @_propagate_inbounds_meta
68,686✔
1023
    @boundscheck setindex_shape_check(X, length(I))
68,686✔
1024
    @boundscheck checkbounds(A, I)
68,686✔
1025
    require_one_based_indexing(X)
68,686✔
1026
    X′ = unalias(A, X)
68,686✔
1027
    I′ = unalias(A, I)
68,686✔
1028
    count = 1
68,686✔
1029
    for i in I′
116,410✔
1030
        @inbounds A[i] = X′[count]
177,031✔
1031
        count += 1
177,031✔
1032
    end
269,224✔
1033
    return A
68,686✔
1034
end
1035

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

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

1073
array_new_memory(mem::Memory, newlen::Int) = typeof(mem)(undef, newlen) # when implemented, this should attempt to first expand mem
8,177,008✔
1074

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

1110
function _growbeg!(a::Vector, delta::Integer)
60,402✔
1111
    @_noub_meta
60,403✔
1112
    delta = Int(delta)
60,403✔
1113
    delta == 0 && return # avoid attempting to index off the end
196,181✔
1114
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
196,178✔
1115
    ref = a.ref
647,819✔
1116
    mem = ref.mem
60,403✔
1117
    len = length(a)
647,819✔
1118
    offset = memoryrefoffset(ref)
647,819✔
1119
    newlen = len + delta
647,819✔
1120
    setfield!(a, :size, (newlen,))
647,819✔
1121
    # if offset is far enough advanced to fit data in existing memory without copying
1122
    if delta <= offset - 1
647,819✔
1123
        setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
477,708✔
1124
    else
1125
        @noinline _growbeg_internal!(a, delta, len)
170,111✔
1126
    end
1127
    return
646,083✔
1128
end
1129

1130
function _growend_internal!(a::Vector, delta::Int, len::Int)
7,968,192✔
1131
    ref = a.ref
7,968,193✔
1132
    mem = ref.mem
7,968,190✔
1133
    memlen = length(mem)
7,968,192✔
1134
    newlen = len + delta
7,968,190✔
1135
    offset = memoryrefoffset(ref)
7,968,189✔
1136
    newmemlen = offset + newlen - 1
7,968,189✔
1137
    if offset + len - 1 > memlen || offset < 1
15,936,363✔
1138
        throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks"))
×
1139
    end
1140

1141
    if offset - 1 > div(5 * newlen, 4)
7,968,186✔
1142
        # If the offset is far enough that we can copy without resizing
1143
        # while maintaining proportional spacing on both ends of the array
1144
        # note that this branch prevents infinite growth when doing combinations
1145
        # of push! and popfirst! (i.e. when using a Vector as a queue)
1146
        newmem = mem
1,072✔
1147
        newoffset = div(newlen, 8) + 1
1,072✔
1148
    else
1149
        # grow either by our computed overallocation factor
1150
        # or exactly the requested size, whichever is larger
1151
        # TODO we should possibly increase the offset if the current offset is nonzero.
1152
        newmemlen2 = max(overallocation(memlen), newmemlen)
8,421,687✔
1153
        newmem = array_new_memory(mem, newmemlen2)
7,967,245✔
1154
        newoffset = offset
7,967,116✔
1155
    end
1156
    newref = @inbounds memoryref(newmem, newoffset)
7,968,188✔
1157
    unsafe_copyto!(newref, ref, len)
8,714,993✔
1158
    if ref !== a.ref
7,968,187✔
1159
        @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently"))
×
1160
    end
1161
    setfield!(a, :ref, newref)
7,968,187✔
1162
return
7,968,186✔
1163
end
1164

1165
function _growend!(a::Vector, delta::Integer)
7,358,658✔
1166
    @_noub_meta
8,037,419✔
1167
    delta = Int(delta)
8,037,419✔
1168
    delta >= 0 || throw(ArgumentError("grow requires delta >= 0"))
16,199,790✔
1169
    ref = a.ref
29,862,044✔
1170
    mem = ref.mem
29,862,040✔
1171
    memlen = length(mem)
29,862,042✔
1172
    len = length(a)
29,862,032✔
1173
    newlen = len + delta
29,862,036✔
1174
    offset = memoryrefoffset(ref)
29,862,023✔
1175
    setfield!(a, :size, (newlen,))
29,862,023✔
1176
    newmemlen = offset + newlen - 1
29,862,023✔
1177
    if memlen < newmemlen
29,862,027✔
1178
        @noinline _growend_internal!(a, delta, len)
7,972,417✔
1179
    end
1180
    return
28,339,961✔
1181
end
1182

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

1200
    # which side would we rather grow into?
1201
    prefer_start = i <= div(len, 2)
821,110✔
1202
    # if offset is far enough advanced to fit data in beginning of the memory
1203
    if prefer_start && delta <= offset - 1
821,110✔
1204
        newref = @inbounds memoryref(mem, offset - delta)
359,318✔
1205
        unsafe_copyto!(newref, ref, i)
629,816✔
1206
        setfield!(a, :ref, newref)
359,318✔
1207
        for j in i:i+delta-1
359,318✔
1208
            @inbounds _unsetindex!(a, j)
504,056✔
1209
        end
504,056✔
1210
    elseif !prefer_start && memlen >= newmemlen
461,792✔
1211
        unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
737,640✔
1212
        for j in i:i+delta-1
421,988✔
1213
            @inbounds _unsetindex!(a, j)
589,826✔
1214
        end
589,826✔
1215
    else
1216
        # since we will allocate the array in the middle of the memory we need at least 2*delta extra space
1217
        # the +1 is because I didn't want to have an off by 1 error.
1218
        newmemlen = max(overallocation(memlen), len+2*delta+1)
53,966✔
1219
        newoffset = (newmemlen - newlen) ÷ 2 + 1
39,804✔
1220
        newmem = array_new_memory(mem, newmemlen)
39,804✔
1221
        newref = @inbounds memoryref(newmem, newoffset)
39,804✔
1222
        unsafe_copyto!(newref, ref, i-1)
74,838✔
1223
        unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
74,838✔
1224
        setfield!(a, :ref, newref)
39,804✔
1225
    end
1226
end
1227

1228
# efficiently delete part of an array
1229
function _deletebeg!(a::Vector, delta::Integer)
250,330✔
1230
    delta = Int(delta)
315,703✔
1231
    len = length(a)
942,375✔
1232
    0 <= delta <= len || throw(ArgumentError("_deletebeg! requires delta in 0:length(a)"))
942,375✔
1233
    for i in 1:delta
317,382✔
1234
        @inbounds _unsetindex!(a, i)
1,110,109✔
1235
    end
336,866✔
1236
    newlen = len - delta
942,375✔
1237
    if newlen != 0 # if newlen==0 we could accidentally index past the memory
942,375✔
1238
        newref = @inbounds memoryref(a.ref, delta + 1)
767,539✔
1239
        setfield!(a, :ref, newref)
767,539✔
1240
    end
1241
    setfield!(a, :size, (newlen,))
942,375✔
1242
    return
942,375✔
1243
end
1244
function _deleteend!(a::Vector, delta::Integer)
1,924,372✔
1245
    delta = Int(delta)
1,924,607✔
1246
    len = length(a)
14,263,631✔
1247
    0 <= delta <= len || throw(ArgumentError("_deleteend! requires delta in 0:length(a)"))
14,263,631✔
1248
    newlen = len - delta
14,263,632✔
1249
    for i in newlen+1:len
14,479,565✔
1250
        @inbounds _unsetindex!(a, i)
23,404,070✔
1251
    end
31,058,087✔
1252
    setfield!(a, :size, (newlen,))
14,263,634✔
1253
    return
14,193,352✔
1254
end
1255
function _deleteat!(a::Vector, i::Integer, delta::Integer)
70,042✔
1256
    i = Int(i)
70,042✔
1257
    len = length(a)
70,042✔
1258
    0 <= delta || throw(ArgumentError("_deleteat! requires delta >= 0"))
70,042✔
1259
    1 <= i <= len || throw(BoundsError(a, i))
70,042✔
1260
    i + delta <= len + 1 || throw(BoundsError(a, i + delta - 1))
70,042✔
1261
    newa = a
70,042✔
1262
    if 2*i + delta <= len
70,042✔
1263
        unsafe_copyto!(newa, 1 + delta, a, 1, i - 1)
1,733✔
1264
        _deletebeg!(a, delta)
1,678✔
1265
    else
1266
        unsafe_copyto!(newa, i, a, i + delta, len + 1 - delta - i)
88,901✔
1267
        _deleteend!(a, delta)
68,364✔
1268
    end
1269
    return
70,042✔
1270
end
1271
## Dequeue functionality ##
1272

1273
"""
1274
    push!(collection, items...) -> collection
1275

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

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

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

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

1297
See also [`pushfirst!`](@ref).
1298
"""
1299
function push! end
1300

1301
function push!(a::Vector{T}, item) where T
6,787,536✔
1302
    @inline
10,570,079✔
1303
    # convert first so we don't grow the array if the assignment won't work
1304
    # and also to avoid a dynamic dynamic dispatch in the common case that
1305
    # `item` is poorly-typed and `a` is well-typed
1306
    item = item isa T ? item : convert(T, item)::T
11,004,937✔
1307
    return _push!(a, item)
22,928,666✔
1308
end
1309
function _push!(a::Vector{T}, item::T) where T
6,787,370✔
1310
    _growend!(a, 1)
22,928,650✔
1311
    @_safeindex a[length(a)] = item
22,928,645✔
1312
    return a
22,912,429✔
1313
end
1314

1315
# specialize and optimize the single argument case
1316
function push!(a::Vector{Any}, @nospecialize x)
864,989✔
1317
    _growend!(a, 1)
1,491,158✔
1318
    @_safeindex a[length(a)] = x
1,491,159✔
1319
    return a
1,491,158✔
1320
end
1321
function push!(a::Vector{Any}, @nospecialize x...)
438✔
1322
    @_terminates_locally_meta
438✔
1323
    na = length(a)
1,668✔
1324
    nx = length(x)
438✔
1325
    _growend!(a, nx)
1,668✔
1326
    @_safeindex for i = 1:nx
2,898✔
1327
        a[na+i] = x[i]
3,336✔
1328
    end
4,566✔
1329
    return a
1,668✔
1330
end
1331

1332
"""
1333
    append!(collection, collections...) -> collection.
1334

1335
For an ordered container `collection`, add the elements of each `collections`
1336
to the end of it.
1337

1338
!!! compat "Julia 1.6"
1339
    Specifying multiple collections to be appended requires at least Julia 1.6.
1340

1341
# Examples
1342
```jldoctest
1343
julia> append!([1], [2, 3])
1344
3-element Vector{Int64}:
1345
 1
1346
 2
1347
 3
1348

1349
julia> append!([1, 2, 3], [4, 5], [6])
1350
6-element Vector{Int64}:
1351
 1
1352
 2
1353
 3
1354
 4
1355
 5
1356
 6
1357
```
1358

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

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

1365
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1366
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1367
"""
1368
function append! end
1369

1370
function append!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
47,665✔
1371
    items isa Tuple && (items = map(x -> convert(T, x), items))
49,683✔
1372
    n = Int(length(items))::Int
383,935✔
1373
    _growend!(a, n)
383,937✔
1374
    copyto!(a, length(a)-n+1, items, firstindex(items), n)
531,804✔
1375
    return a
383,936✔
1376
end
1377

1378
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
1,097,691✔
1379
push!(a::AbstractVector, iter...) = append!(a, iter)
1,910✔
1380
append!(a::AbstractVector, iter...) = (foreach(v -> append!(a, v), iter); a)
×
1381

1382
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
211,721✔
1383
    n = Int(length(iter))::Int
216,246✔
1384
    i = lastindex(a)
211,721✔
1385
    sizehint!(a, length(a) + n; shrink=false)
211,721✔
1386
    for item in iter
303,330✔
1387
        push!(a, item)
818,284✔
1388
    end
889,072✔
1389
    a
211,721✔
1390
end
1391
function _append!(a::AbstractVector, ::IteratorSize, iter)
885,970✔
1392
    for item in iter
997,525✔
1393
        push!(a, item)
989,729✔
1394
    end
998,755✔
1395
    a
885,970✔
1396
end
1397

1398
"""
1399
    prepend!(a::Vector, collections...) -> collection
1400

1401
Insert the elements of each `collections` to the beginning of `a`.
1402

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

1406
!!! compat "Julia 1.6"
1407
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1408

1409
# Examples
1410
```jldoctest
1411
julia> prepend!([3], [1, 2])
1412
3-element Vector{Int64}:
1413
 1
1414
 2
1415
 3
1416

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

1429
function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
26✔
1430
    items isa Tuple && (items = map(x -> convert(T, x), items))
21✔
1431
    n = length(items)
132✔
1432
    _growbeg!(a, n)
251✔
1433
    # in case of aliasing, the _growbeg might have shifted our data, so copy
1434
    # just the last n elements instead of all of them from the first
1435
    copyto!(a, 1, items, lastindex(items)-n+1, n)
251✔
1436
    return a
132✔
1437
end
1438

1439
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
×
1440
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
×
1441
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)
×
1442

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

1466
"""
1467
    resize!(a::Vector, n::Integer) -> a
1468

1469
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1470
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1471
guaranteed to be initialized.
1472

1473
# Examples
1474
```jldoctest
1475
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1476
3-element Vector{Int64}:
1477
 6
1478
 5
1479
 4
1480

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

1483
julia> length(a)
1484
8
1485

1486
julia> a[1:6]
1487
6-element Vector{Int64}:
1488
 6
1489
 5
1490
 4
1491
 3
1492
 2
1493
 1
1494
```
1495
"""
1496
function resize!(a::Vector, nl_::Integer)
5,728,240✔
1497
    nl = Int(nl_)::Int
5,728,284✔
1498
    l = length(a)
6,028,689✔
1499
    if nl > l
6,028,688✔
1500
        _growend!(a, nl-l)
3,429,359✔
1501
    elseif nl != l
2,599,332✔
1502
        if nl < 0
683,073✔
1503
            _throw_argerror("new length must be ≥ 0")
×
1504
        end
1505
        _deleteend!(a, l-nl)
683,073✔
1506
    end
1507
    return a
6,028,681✔
1508
end
1509

1510
"""
1511
    sizehint!(s, n; first::Bool=false, shrink::Bool=true) -> s
1512

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

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

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

1526
See also [`resize!`](@ref).
1527

1528
# Notes on the performance model
1529

1530
For types that support `sizehint!`,
1531

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

1536
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1537
   `Base`.
1538

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

1541
!!! compat "Julia 1.11"
1542
    The `shrink` and `first` arguments were added in Julia 1.11.
1543
"""
1544
function sizehint! end
1545

1546
function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
490,432✔
1547
    len = length(a)
244,079✔
1548
    ref = a.ref
244,079✔
1549
    mem = ref.mem
244,079✔
1550
    memlen = length(mem)
244,079✔
1551
    sz = max(Int(sz), len)
244,079✔
1552
    inc = sz - len
244,079✔
1553
    if sz <= memlen
244,079✔
1554
        # if we don't save at least 1/8th memlen then its not worth it to shrink
1555
        if !shrink || memlen - sz <= div(memlen, 8)
172,028✔
1556
            return a
170,964✔
1557
        end
1558
        newmem = array_new_memory(mem, sz)
598✔
1559
        if first
466✔
1560
            newref = memoryref(newmem, inc + 1)
×
1561
        else
1562
            newref = memoryref(newmem)
466✔
1563
        end
1564
        unsafe_copyto!(newref, ref, len)
693✔
1565
        setfield!(a, :ref, newref)
466✔
1566
    elseif first
72,649✔
1567
        _growbeg!(a, inc)
×
1568
        newref = getfield(a, :ref)
×
1569
        newref = memoryref(newref, inc + 1)
×
1570
        setfield!(a, :size, (len,)) # undo the size change from _growbeg!
×
1571
        setfield!(a, :ref, newref) # undo the offset change from _growbeg!
×
1572
    else # last
1573
        _growend!(a, inc)
72,649✔
1574
        setfield!(a, :size, (len,)) # undo the size change from _growend!
72,649✔
1575
    end
1576
    a
73,115✔
1577
end
1578

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

1588
"""
1589
    pop!(collection) -> item
1590

1591
Remove an item in `collection` and return it. If `collection` is an
1592
ordered container, the last item is returned; for unordered containers,
1593
an arbitrary element is returned.
1594

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

1597
# Examples
1598
```jldoctest
1599
julia> A=[1, 2, 3]
1600
3-element Vector{Int64}:
1601
 1
1602
 2
1603
 3
1604

1605
julia> pop!(A)
1606
3
1607

1608
julia> A
1609
2-element Vector{Int64}:
1610
 1
1611
 2
1612

1613
julia> S = Set([1, 2])
1614
Set{Int64} with 2 elements:
1615
  2
1616
  1
1617

1618
julia> pop!(S)
1619
2
1620

1621
julia> S
1622
Set{Int64} with 1 element:
1623
  1
1624

1625
julia> pop!(Dict(1=>2))
1626
1 => 2
1627
```
1628
"""
1629
function pop!(a::Vector)
1,764,888✔
1630
    if isempty(a)
13,140,407✔
1631
        _throw_argerror("array must be non-empty")
×
1632
    end
1633
    item = a[end]
13,140,409✔
1634
    _deleteend!(a, 1)
13,140,409✔
1635
    return item
13,070,132✔
1636
end
1637

1638
"""
1639
    popat!(a::Vector, i::Integer, [default])
1640

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

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

1648
!!! compat "Julia 1.5"
1649
    This function is available as of Julia 1.5.
1650

1651
# Examples
1652
```jldoctest
1653
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1654
3
1655

1656
julia> a
1657
3-element Vector{Int64}:
1658
 4
1659
 2
1660
 1
1661

1662
julia> popat!(a, 4, missing)
1663
missing
1664

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

1677
function popat!(a::Vector, i::Integer, default)
×
1678
    if 1 <= i <= length(a)
×
1679
        x = @inbounds a[i]
×
1680
        _deleteat!(a, i, 1)
×
1681
        x
×
1682
    else
1683
        default
×
1684
    end
1685
end
1686

1687
"""
1688
    pushfirst!(collection, items...) -> collection
1689

1690
Insert one or more `items` at the beginning of `collection`.
1691

1692
This function is called `unshift` in many other programming languages.
1693

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

1717
# specialize and optimize the single argument case
1718
function pushfirst!(a::Vector{Any}, @nospecialize x)
43,444✔
1719
    _growbeg!(a, 1)
509,705✔
1720
    @_safeindex a[1] = x
495,080✔
1721
    return a
495,080✔
1722
end
1723
function pushfirst!(a::Vector{Any}, @nospecialize x...)
1724
    @_terminates_locally_meta
×
1725
    na = length(a)
×
1726
    nx = length(x)
×
1727
    _growbeg!(a, nx)
×
1728
    @_safeindex for i = 1:nx
×
1729
        a[i] = x[i]
×
1730
    end
×
1731
    return a
×
1732
end
1733

1734
"""
1735
    popfirst!(collection) -> item
1736

1737
Remove the first `item` from `collection`.
1738

1739
This function is called `shift` in many other programming languages.
1740

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

1743
# Examples
1744
```jldoctest
1745
julia> A = [1, 2, 3, 4, 5, 6]
1746
6-element Vector{Int64}:
1747
 1
1748
 2
1749
 3
1750
 4
1751
 5
1752
 6
1753

1754
julia> popfirst!(A)
1755
1
1756

1757
julia> A
1758
5-element Vector{Int64}:
1759
 2
1760
 3
1761
 4
1762
 5
1763
 6
1764
```
1765
"""
1766
function popfirst!(a::Vector)
97,342✔
1767
    if isempty(a)
940,598✔
1768
        _throw_argerror("array must be non-empty")
×
1769
    end
1770
    item = a[1]
940,598✔
1771
    _deletebeg!(a, 1)
940,598✔
1772
    return item
940,598✔
1773
end
1774

1775
"""
1776
    insert!(a::Vector, index::Integer, item)
1777

1778
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1779
the resulting `a`.
1780

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

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

1810
"""
1811
    deleteat!(a::Vector, i::Integer)
1812

1813
Remove the item at the given `i` and return the modified `a`. Subsequent items
1814
are shifted to fill the resulting gap.
1815

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

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

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

1847
"""
1848
    deleteat!(a::Vector, inds)
1849

1850
Remove the items at the indices given by `inds`, and return the modified `a`.
1851
Subsequent items are shifted to fill the resulting gap.
1852

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

1856
# Examples
1857
```jldoctest
1858
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1859
3-element Vector{Int64}:
1860
 5
1861
 3
1862
 1
1863

1864
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1865
3-element Vector{Int64}:
1866
 5
1867
 3
1868
 1
1869

1870
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1871
ERROR: ArgumentError: indices must be unique and sorted
1872
Stacktrace:
1873
[...]
1874
```
1875
"""
1876
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
×
1877
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
800✔
1878

1879
struct Nowhere; end
1880
push!(::Nowhere, _) = nothing
96✔
1881
_growend!(::Nowhere, _) = nothing
×
1882

1883
function _push_deleted!(dltd, a::Vector, ind)
192✔
1884
    @_propagate_inbounds_meta
192✔
1885
    if isassigned(a, ind)
938✔
1886
        push!(dltd, a[ind])
938✔
1887
    else
1888
        _growend!(dltd, 1)
×
1889
    end
1890
end
1891

1892
function _copy_item!(a::Vector, p, q)
112✔
1893
    @_propagate_inbounds_meta
112✔
1894
    if isassigned(a, q)
513✔
1895
        a[p] = a[q]
513✔
1896
    else
1897
        _unsetindex!(a, p)
×
1898
    end
1899
end
1900

1901
function _deleteat!(a::Vector, inds, dltd=Nowhere())
956✔
1902
    n = length(a)
1,600✔
1903
    y = iterate(inds)
800✔
1904
    y === nothing && return a
800✔
1905
    (p, s) = y
795✔
1906
    checkbounds(a, p)
795✔
1907
    @inbounds _push_deleted!(dltd, a, p)
795✔
1908
    q = p+1
795✔
1909
    while true
938✔
1910
        y = iterate(inds, s)
938✔
1911
        y === nothing && break
938✔
1912
        (i,s) = y
143✔
1913
        if !(q <= i <= n)
143✔
1914
            if i < q
×
1915
                _throw_argerror("indices must be unique and sorted")
×
1916
            else
1917
                throw(BoundsError())
×
1918
            end
1919
        end
1920
        while q < i
231✔
1921
            @inbounds _copy_item!(a, p, q)
88✔
1922
            p += 1; q += 1
88✔
1923
        end
88✔
1924
        @inbounds _push_deleted!(dltd, a, i)
143✔
1925
        q = i+1
143✔
1926
    end
143✔
1927
    while q <= n
1,220✔
1928
        @inbounds _copy_item!(a, p, q)
425✔
1929
        p += 1; q += 1
425✔
1930
    end
425✔
1931
    _deleteend!(a, n-p+1)
902✔
1932
    return a
795✔
1933
end
1934

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

1948
const _default_splice = []
1949

1950
"""
1951
    splice!(a::Vector, index::Integer, [replacement]) -> item
1952

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

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

1960
# Examples
1961
```jldoctest
1962
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1963
2
1964

1965
julia> A
1966
5-element Vector{Int64}:
1967
 6
1968
 5
1969
 4
1970
 3
1971
 1
1972

1973
julia> splice!(A, 5, -1)
1974
1
1975

1976
julia> A
1977
5-element Vector{Int64}:
1978
  6
1979
  5
1980
  4
1981
  3
1982
 -1
1983

1984
julia> splice!(A, 1, [-1, -2, -3])
1985
6
1986

1987
julia> A
1988
7-element Vector{Int64}:
1989
 -1
1990
 -2
1991
 -3
1992
  5
1993
  4
1994
  3
1995
 -1
1996
```
1997

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

2019
"""
2020
    splice!(a::Vector, indices, [replacement]) -> items
2021

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

2028
To insert `replacement` before an index `n` without removing any items, use
2029
`splice!(collection, n:n-1, replacement)`.
2030

2031
$(_DOCS_ALIASING_WARNING)
2032

2033
!!! compat "Julia 1.5"
2034
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
2035

2036
!!! compat "Julia 1.8"
2037
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
2038

2039
# Examples
2040
```jldoctest
2041
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
2042
Int64[]
2043

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

2064
    n = length(a)
192,781✔
2065
    f = first(r)
192,781✔
2066
    l = last(r)
192,781✔
2067
    d = length(r)
192,781✔
2068

2069
    if m < d
192,781✔
2070
        delta = d - m
×
2071
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
×
2072
    elseif m > d
192,781✔
2073
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
192,781✔
2074
    end
2075

2076
    k = 1
192,781✔
2077
    for x in ins
192,781✔
2078
        a[f+k-1] = x
578,343✔
2079
        k += 1
578,343✔
2080
    end
727,688✔
2081
    return v
192,781✔
2082
end
2083

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

2086
function empty!(a::Vector)
38,510✔
2087
    _deleteend!(a, length(a))
556,821✔
2088
    return a
434,444✔
2089
end
2090

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

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

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

2143
"""
2144
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
2145

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

2149
# Examples
2150
```jldoctest
2151
julia> A = Vector(1:5)
2152
5-element Vector{Int64}:
2153
 1
2154
 2
2155
 3
2156
 4
2157
 5
2158

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

2167
julia> reverse(A, 1, 4)
2168
5-element Vector{Int64}:
2169
 4
2170
 3
2171
 2
2172
 1
2173
 5
2174

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

2199
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
2200
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
2201
    @eval begin
2202
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
1,190,436✔
2203
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
88,802✔
2204
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
2205
        function $_f(A::AbstractVector, dim::Integer)
×
2206
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
×
2207
            return $_f(A, :)
×
2208
        end
2209
    end
2210
end
2211

2212
function reverseind(a::AbstractVector, i::Integer)
×
2213
    li = LinearIndices(a)
×
2214
    first(li) + last(li) - i
×
2215
end
2216

2217
# This implementation of `midpoint` is performance-optimized but safe
2218
# only if `lo <= hi`.
2219
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
438,695✔
2220
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
2221

2222
"""
2223
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
2224

2225
In-place version of [`reverse`](@ref).
2226

2227
# Examples
2228
```jldoctest
2229
julia> A = Vector(1:5)
2230
5-element Vector{Int64}:
2231
 1
2232
 2
2233
 3
2234
 4
2235
 5
2236

2237
julia> reverse!(A);
2238

2239
julia> A
2240
5-element Vector{Int64}:
2241
 5
2242
 4
2243
 3
2244
 2
2245
 1
2246
```
2247
"""
2248
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
1,032,199✔
2249
    s, n = Int(start), Int(stop)
1,954,207✔
2250
    if n > s # non-empty and non-trivial
1,021,789✔
2251
        liv = LinearIndices(v)
293,853✔
2252
        if !(first(liv) ≤ s ≤ last(liv))
293,853✔
2253
            throw(BoundsError(v, s))
×
2254
        elseif !(first(liv) ≤ n ≤ last(liv))
293,853✔
2255
            throw(BoundsError(v, n))
×
2256
        end
2257
        r = n
293,853✔
2258
        @inbounds for i in s:midpoint(s, n-1)
293,853✔
2259
            v[i], v[r] = v[r], v[i]
301,815✔
2260
            r -= 1
301,815✔
2261
        end
309,777✔
2262
    end
2263
    return v
1,021,789✔
2264
end
2265

2266
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2267

2268
vcat() = Vector{Any}()
×
2269
hcat() = Vector{Any}()
×
2270

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

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

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

2301
## find ##
2302

2303
"""
2304
    findnext(A, i)
2305

2306
Find the next index after or including `i` of a `true` element of `A`,
2307
or `nothing` if not found.
2308

2309
Indices are of the same type as those returned by [`keys(A)`](@ref)
2310
and [`pairs(A)`](@ref).
2311

2312
# Examples
2313
```jldoctest
2314
julia> A = [false, false, true, false]
2315
4-element Vector{Bool}:
2316
 0
2317
 0
2318
 1
2319
 0
2320

2321
julia> findnext(A, 1)
2322
3
2323

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

2326
julia> A = [false false; true false]
2327
2×2 Matrix{Bool}:
2328
 0  0
2329
 1  0
2330

2331
julia> findnext(A, CartesianIndex(1, 1))
2332
CartesianIndex(2, 1)
2333
```
2334
"""
2335
findnext(A, start) = findnext(identity, A, start)
×
2336

2337
"""
2338
    findfirst(A)
2339

2340
Return the index or key of the first `true` value in `A`.
2341
Return `nothing` if no such value is found.
2342
To search for other kinds of values, pass a predicate as the first argument.
2343

2344
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2345
and [`pairs(A)`](@ref).
2346

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

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

2358
julia> findfirst(A)
2359
3
2360

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

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

2368
julia> findfirst(A)
2369
CartesianIndex(2, 1)
2370
```
2371
"""
2372
findfirst(A) = findfirst(identity, A)
×
2373

2374
# Needed for bootstrap, and allows defining only an optimized findnext method
2375
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
76✔
2376

2377
"""
2378
    findnext(predicate::Function, A, i)
2379

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

2385
Indices are of the same type as those returned by [`keys(A)`](@ref)
2386
and [`pairs(A)`](@ref).
2387

2388
# Examples
2389
```jldoctest
2390
julia> A = [1, 4, 2, 2];
2391

2392
julia> findnext(isodd, A, 1)
2393
1
2394

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

2397
julia> A = [1 4; 2 2];
2398

2399
julia> findnext(isodd, A, CartesianIndex(1, 1))
2400
CartesianIndex(1, 1)
2401

2402
julia> findnext(isspace, "a b c", 3)
2403
4
2404
```
2405
"""
2406
function findnext(testf::Function, A, start)
249,115✔
2407
    i = oftype(first(keys(A)), start)
250,694✔
2408
    l = last(keys(A))
1,135,679✔
2409
    i > l && return nothing
1,135,679✔
2410
    while true
604,267✔
2411
        testf(A[i]) && return i
618,362✔
2412
        i == l && break
536,222✔
2413
        # nextind(A, l) can throw/overflow
2414
        i = nextind(A, i)
349,835✔
2415
    end
349,835✔
2416
    return nothing
186,387✔
2417
end
2418

2419
"""
2420
    findfirst(predicate::Function, A)
2421

2422
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2423
Return `nothing` if there is no such element.
2424

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

2428
# Examples
2429
```jldoctest
2430
julia> A = [1, 4, 2, 2]
2431
4-element Vector{Int64}:
2432
 1
2433
 4
2434
 2
2435
 2
2436

2437
julia> findfirst(iseven, A)
2438
2
2439

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

2442
julia> findfirst(isequal(4), A)
2443
2
2444

2445
julia> A = [1 4; 2 2]
2446
2×2 Matrix{Int64}:
2447
 1  4
2448
 2  2
2449

2450
julia> findfirst(iseven, A)
2451
CartesianIndex(2, 1)
2452
```
2453
"""
2454
function findfirst(testf::Function, A)
1✔
2455
    for (i, a) in pairs(A)
1✔
2456
        testf(a) && return i
×
2457
    end
×
2458
    return nothing
1✔
2459
end
2460

2461
# Needed for bootstrap, and allows defining only an optimized findnext method
2462
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
2,151,050✔
2463
    findnext(testf, A, first(keys(A)))
2464

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

2468
findfirst(::typeof(iszero), ::OneTo) = nothing
×
2469
findfirst(::typeof(isone), r::OneTo) = isempty(r) ? nothing : oneunit(keytype(r))
×
2470

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

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

2485
findfirst(::typeof(iszero), r::AbstractRange) = findfirst(==(zero(first(r))), r)
×
2486
findfirst(::typeof(isone), r::AbstractRange) = findfirst(==(one(first(r))), r)
×
2487

2488
"""
2489
    findprev(A, i)
2490

2491
Find the previous index before or including `i` of a `true` element of `A`,
2492
or `nothing` if not found.
2493

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

2497
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2498

2499
# Examples
2500
```jldoctest
2501
julia> A = [false, false, true, true]
2502
4-element Vector{Bool}:
2503
 0
2504
 0
2505
 1
2506
 1
2507

2508
julia> findprev(A, 3)
2509
3
2510

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

2513
julia> A = [false false; true true]
2514
2×2 Matrix{Bool}:
2515
 0  0
2516
 1  1
2517

2518
julia> findprev(A, CartesianIndex(2, 1))
2519
CartesianIndex(2, 1)
2520
```
2521
"""
2522
findprev(A, start) = findprev(identity, A, start)
×
2523

2524
"""
2525
    findlast(A)
2526

2527
Return the index or key of the last `true` value in `A`.
2528
Return `nothing` if there is no `true` value in `A`.
2529

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

2533
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2534

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

2544
julia> findlast(A)
2545
3
2546

2547
julia> A = falses(2,2);
2548

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

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

2556
julia> findlast(A)
2557
CartesianIndex(2, 1)
2558
```
2559
"""
2560
findlast(A) = findlast(identity, A)
×
2561

2562
# Needed for bootstrap, and allows defining only an optimized findprev method
2563
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
240✔
2564

2565
"""
2566
    findprev(predicate::Function, A, i)
2567

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

2573
Indices are of the same type as those returned by [`keys(A)`](@ref)
2574
and [`pairs(A)`](@ref).
2575

2576
# Examples
2577
```jldoctest
2578
julia> A = [4, 6, 1, 2]
2579
4-element Vector{Int64}:
2580
 4
2581
 6
2582
 1
2583
 2
2584

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

2587
julia> findprev(isodd, A, 3)
2588
3
2589

2590
julia> A = [4 6; 1 2]
2591
2×2 Matrix{Int64}:
2592
 4  6
2593
 1  2
2594

2595
julia> findprev(isodd, A, CartesianIndex(1, 2))
2596
CartesianIndex(2, 1)
2597

2598
julia> findprev(isspace, "a b c", 3)
2599
2
2600
```
2601
"""
2602
function findprev(testf::Function, A, start)
97✔
2603
    f = first(keys(A))
158✔
2604
    i = oftype(f, start)
158✔
2605
    i < f && return nothing
158✔
2606
    while true
599✔
2607
        testf(A[i]) && return i
874✔
2608
        i == f && break
444✔
2609
        # prevind(A, f) can throw/underflow
2610
        i = prevind(A, i)
441✔
2611
    end
441✔
2612
    return nothing
3✔
2613
end
2614

2615
"""
2616
    findlast(predicate::Function, A)
2617

2618
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2619
Return `nothing` if there is no such element.
2620

2621
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2622
and [`pairs(A)`](@ref).
2623

2624
# Examples
2625
```jldoctest
2626
julia> A = [1, 2, 3, 4]
2627
4-element Vector{Int64}:
2628
 1
2629
 2
2630
 3
2631
 4
2632

2633
julia> findlast(isodd, A)
2634
3
2635

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

2638
julia> A = [1 2; 3 4]
2639
2×2 Matrix{Int64}:
2640
 1  2
2641
 3  4
2642

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

2654
# Needed for bootstrap, and allows defining only an optimized findprev method
2655
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
416✔
2656
    findprev(testf, A, last(keys(A)))
2657

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

2664
function findlast(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T},typeof(iszero),typeof(isone)},
×
2665
        r::StepRange{T,S}) where {T,S}
2666
    findfirst(p, r)
×
2667
end
2668

2669
"""
2670
    findall(f::Function, A)
2671

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

2675
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2676
and [`pairs(A)`](@ref).
2677

2678
# Examples
2679
```jldoctest
2680
julia> x = [1, 3, 4]
2681
3-element Vector{Int64}:
2682
 1
2683
 3
2684
 4
2685

2686
julia> findall(isodd, x)
2687
2-element Vector{Int64}:
2688
 1
2689
 2
2690

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

2700
julia> findall(!iszero, A)
2701
4-element Vector{CartesianIndex{2}}:
2702
 CartesianIndex(1, 1)
2703
 CartesianIndex(2, 1)
2704
 CartesianIndex(1, 2)
2705
 CartesianIndex(2, 2)
2706

2707
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2708
Dict{Symbol, Int64} with 3 entries:
2709
  :A => 10
2710
  :B => -1
2711
  :C => 0
2712

2713
julia> findall(≥(0), d)
2714
2-element Vector{Symbol}:
2715
 :A
2716
 :C
2717

2718
```
2719
"""
2720
function findall(testf::Function, A)
×
2721
    gen = (first(p) for p in pairs(A) if testf(last(p)))
×
2722
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
×
2723
end
2724

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

2729
"""
2730
    findall(A)
2731

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

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

2739
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2740

2741
# Examples
2742
```jldoctest
2743
julia> A = [true, false, false, true]
2744
4-element Vector{Bool}:
2745
 1
2746
 0
2747
 0
2748
 1
2749

2750
julia> findall(A)
2751
2-element Vector{Int64}:
2752
 1
2753
 4
2754

2755
julia> A = [true false; false true]
2756
2×2 Matrix{Bool}:
2757
 1  0
2758
 0  1
2759

2760
julia> findall(A)
2761
2-element Vector{CartesianIndex{2}}:
2762
 CartesianIndex(1, 1)
2763
 CartesianIndex(2, 2)
2764

2765
julia> findall(falses(3))
2766
Int64[]
2767
```
2768
"""
2769
function findall(A)
×
2770
    collect(first(p) for p in pairs(A) if last(p))
×
2771
end
2772

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

2787
findall(x::Bool) = x ? [1] : Vector{Int}()
×
2788
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
×
2789
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
×
2790

2791
# similar to Matlab's ismember
2792
"""
2793
    indexin(a, b)
2794

2795
Return an array containing the first index in `b` for
2796
each value in `a` that is a member of `b`. The output
2797
array contains `nothing` wherever `a` is not a member of `b`.
2798

2799
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2800

2801
# Examples
2802
```jldoctest
2803
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2804

2805
julia> b = ['a', 'b', 'c'];
2806

2807
julia> indexin(a, b)
2808
6-element Vector{Union{Nothing, Int64}}:
2809
 1
2810
 2
2811
 3
2812
 2
2813
  nothing
2814
 1
2815

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

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

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

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

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

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

2923
## Filter ##
2924

2925
"""
2926
    filter(f, a)
2927

2928
Return a copy of collection `a`, removing elements for which `f` is `false`.
2929
The function `f` is passed one argument.
2930

2931
!!! compat "Julia 1.4"
2932
    Support for `a` as a tuple requires at least Julia 1.4.
2933

2934
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2935

2936
# Examples
2937
```jldoctest
2938
julia> a = 1:10
2939
1:10
2940

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

2962
function filter(f, a::AbstractArray)
×
2963
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
×
2964

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

2979
"""
2980
    filter!(f, a)
2981

2982
Update collection `a`, removing elements for which `f` is `false`.
2983
The function `f` is passed one argument.
2984

2985
# Examples
2986
```jldoctest
2987
julia> filter!(isodd, Vector(1:10))
2988
5-element Vector{Int64}:
2989
 1
2990
 3
2991
 5
2992
 7
2993
 9
2994
```
2995
"""
2996
function filter!(f, a::AbstractVector)
758,470✔
2997
    j = firstindex(a)
758,471✔
2998
    for ai in a
1,555,934✔
2999
        @inbounds a[j] = ai
2,888,154✔
3000
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
2,888,329✔
3001
    end
2,888,154✔
3002
    j > lastindex(a) && return a
1,555,934✔
3003
    if a isa Vector
328✔
3004
        resize!(a, j-1)
328✔
3005
        sizehint!(a, j-1)
328✔
3006
    else
3007
        deleteat!(a, j:lastindex(a))
×
3008
    end
3009
    return a
328✔
3010
end
3011

3012
"""
3013
    filter(f)
3014

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

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

3021
# Examples
3022
```jldoctest
3023
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
3024
(1, 2, 4, 6)
3025

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

3039
"""
3040
    keepat!(a::Vector, inds)
3041
    keepat!(a::BitVector, inds)
3042

3043
Remove the items at all the indices which are not given by `inds`,
3044
and return the modified `a`.
3045
Items which are kept are shifted to fill the resulting gaps.
3046

3047
$(_DOCS_ALIASING_WARNING)
3048

3049
`inds` must be an iterator of sorted and unique integer indices.
3050
See also [`deleteat!`](@ref).
3051

3052
!!! compat "Julia 1.7"
3053
    This function is available as of Julia 1.7.
3054

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

3066
"""
3067
    keepat!(a::Vector, m::AbstractVector{Bool})
3068
    keepat!(a::BitVector, m::AbstractVector{Bool})
3069

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

3074
# Examples
3075
```jldoctest
3076
julia> a = [:a, :b, :c];
3077

3078
julia> keepat!(a, [true, false, true])
3079
2-element Vector{Symbol}:
3080
 :a
3081
 :c
3082

3083
julia> a
3084
2-element Vector{Symbol}:
3085
 :a
3086
 :c
3087
```
3088
"""
3089
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
×
3090

3091
# set-like operators for vectors
3092
# These are moderately efficient, preserve order, and remove dupes.
3093

3094
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
178✔
3095
    # P, U force specialization
3096
    if pred(x, state)
399✔
3097
        update!(state, x)
82✔
3098
        true
3099
    else
3100
        false
3101
    end
3102
end
3103

3104
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
2✔
3105
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
86✔
3106

3107
function _grow!(pred!, v::AbstractVector, itrs)
3108
    filter!(pred!, v) # uniquify v
2✔
3109
    for itr in itrs
2✔
3110
        mapfilter(pred!, push!, itr, v)
4✔
3111
    end
6✔
3112
    return v
2✔
3113
end
3114

3115
union!(v::AbstractVector{T}, itrs...) where {T} =
2✔
3116
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
3117

3118
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
×
3119
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
3120

3121
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
×
3122
    seen = Set{eltype(v)}()
×
3123
    filter!(_grow_filter!(seen), v)
×
3124
    shrinker!(seen, itrs...)
×
3125
    filter!(in(seen), v)
×
3126
end
3127

3128
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
×
3129
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
×
3130

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

3133
function _shrink(shrinker!::F, itr, itrs) where F
86✔
3134
    T = promote_eltype(itr, itrs...)
86✔
3135
    keep = shrinker!(Set{T}(itr), itrs...)
86✔
3136
    vectorfilter(T, _shrink_filter!(keep), itr)
86✔
3137
end
3138

3139
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
81✔
3140
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
5✔
3141

3142
function intersect(v::AbstractVector, r::AbstractRange)
×
3143
    T = promote_eltype(v, r)
×
3144
    common = Iterators.filter(in(r), v)
×
3145
    seen = Set{T}(common)
×
3146
    return vectorfilter(T, _shrink_filter!(seen), common)
×
3147
end
3148
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
×
3149

3150
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
3151
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
415,370✔
3152
    if i isa Bool # Not via dispatch to avoid ambiguities
416,129✔
3153
        throw(ArgumentError("invalid index: $i of type Bool"))
×
3154
    else
3155
        _getindex(v, i)
2,802,043✔
3156
    end
3157
end
3158

3159
"""
3160
    wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
3161

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

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

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

3181
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
×
3182
    dims = convert(Dims, dims)
×
3183
    ref = _wrap(m, dims)
×
3184
    $(Expr(:new, :(Array{T, N}), :ref, :dims))
×
3185
end
3186

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