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

JuliaLang / julia / #37616

10 Sep 2023 01:51AM UTC coverage: 86.489% (+0.3%) from 86.196%
#37616

push

local

web-flow
Make _global_logstate a typed global (#51257)

73902 of 85447 relevant lines covered (86.49%)

13068259.04 hits per line

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

93.16
/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
13,334✔
13
end
14
DimensionMismatch() = DimensionMismatch("")
8✔
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
using Core: arraysize, arrayset, const_arrayref
124

125
"""
126
    @_safeindex
127

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

160
vect() = Vector{Any}()
25,133,341✔
161
function vect(X::T...) where T
169,911✔
162
    @_terminates_locally_meta
83,182✔
163
    vec = Vector{T}(undef, length(X))
1,267,655✔
164
    @_safeindex for i = 1:length(X)
259,252✔
165
        vec[i] = X[i]
4,407,808✔
166
    end
6,446,083✔
167
    return vec
165,785✔
168
end
169

170
"""
171
    vect(X...)
172

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

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

190
size(a::Array, d::Integer) = arraysize(a, d isa Int ? d : convert(Int, d))
3,060,174✔
191
size(a::Vector) = (arraysize(a,1),)
2,147,483,647✔
192
size(a::Matrix) = (arraysize(a,1), arraysize(a,2))
6,421,271✔
193
size(a::Array{<:Any,N}) where {N} = (@inline; ntuple(M -> size(a, M), Val(N))::Dims)
2,784,691✔
194

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

197
allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0))
2,969,483✔
198

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

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

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

209
julia> Base.isbitsunion(Union{Float64, String})
210
false
211
```
212
"""
213
isbitsunion(u::Union) = allocatedinline(u)
1,308✔
214
isbitsunion(x) = false
28,503✔
215

216
function _unsetindex!(A::Array{T}, i::Int) where {T}
73,076✔
217
    @inline
5,574✔
218
    @boundscheck checkbounds(A, i)
6,171,975✔
219
    t = @_gc_preserve_begin A
6,172,163✔
220
    p = Ptr{Ptr{Cvoid}}(pointer(A, i))
6,171,516✔
221
    if !allocatedinline(T)
5,574✔
222
        Intrinsics.atomic_pointerset(p, C_NULL, :monotonic)
5,911,162✔
223
    elseif T isa DataType
4,801✔
224
        if !datatype_pointerfree(T)
4,801✔
225
            for j = 1:Core.sizeof(Ptr{Cvoid}):Core.sizeof(T)
4,184✔
226
                Intrinsics.atomic_pointerset(p + j - 1, C_NULL, :monotonic)
4,277✔
227
            end
7,153✔
228
        end
229
    end
230
    @_gc_preserve_end t
6,172,223✔
231
    return A
6,171,633✔
232
end
233

234

235
"""
236
    Base.bitsunionsize(U::Union) -> Int
237

238
For a `Union` of [`isbitstype`](@ref) types, return the size of the largest type; assumes `Base.isbitsunion(U) == true`.
239

240
# Examples
241
```jldoctest
242
julia> Base.bitsunionsize(Union{Float64, UInt8})
243
8
244

245
julia> Base.bitsunionsize(Union{Float64, UInt8, Int128})
246
16
247
```
248
"""
249
function bitsunionsize(u::Union)
4✔
250
    isinline, sz, _ = uniontype_layout(u)
4✔
251
    @assert isinline
4✔
252
    return sz
4✔
253
end
254

255
elsize(@nospecialize _::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
1,697,387✔
256
function elsize(::Type{Ptr{T}}) where T
8✔
257
    # this only must return something valid for values which satisfy is_valid_intrinsic_elptr(T),
258
    # which includes Any and most concrete datatypes
259
    T === Any && return sizeof(Ptr{Any})
8✔
260
    T isa DataType || sizeof(Any) # throws
7✔
261
    return LLT_ALIGN(Core.sizeof(T), datatype_alignment(T))
5✔
262
end
263
elsize(::Type{Union{}}, slurp...) = 0
×
264
sizeof(a::Array) = Core.sizeof(a)
3,423,062✔
265

266
function isassigned(a::Array, i::Int...)
12,570,701✔
267
    @inline
7,422,074✔
268
    @boundscheck checkbounds(Bool, a, i...) || return false
2,147,483,647✔
269
    ii = (_sub2ind(size(a), i...) % UInt) - 1
2,147,483,647✔
270
    ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii) == 1
2,147,483,647✔
271
end
272

273
## copy ##
274

275
"""
276
    unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, N)
277

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

281
The `unsafe` prefix on this function indicates that no validation is performed on the
282
pointers `dest` and `src` to ensure that they are valid. Incorrect usage may corrupt or
283
segfault your program, in the same manner as C.
284
"""
285
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
38,732,774✔
286
    # Do not use this to copy data between pointer arrays.
287
    # It can't be made safe no matter how carefully you checked.
288
    memmove(dest, src, n * aligned_sizeof(T))
55,599,936✔
289
    return dest
54,776,834✔
290
end
291

292

293
function _unsafe_copyto!(dest, doffs, src, soffs, n)
33,495,148✔
294
    destp = pointer(dest, doffs)
33,495,148✔
295
    srcp = pointer(src, soffs)
33,495,148✔
296
    @inbounds if destp < srcp || destp > srcp + n
52,710,898✔
297
        for i = 1:n
66,990,294✔
298
            if isassigned(src, soffs + i - 1)
222,238,614✔
299
                dest[doffs + i - 1] = src[soffs + i - 1]
225,770,304✔
300
            else
301
                _unsetindex!(dest, doffs + i - 1)
×
302
            end
303
        end
410,981,841✔
304
    else
305
        for i = n:-1:1
×
306
            if isassigned(src, soffs + i - 1)
×
307
                dest[doffs + i - 1] = src[soffs + i - 1]
×
308
            else
309
                _unsetindex!(dest, doffs + i - 1)
×
310
            end
311
        end
×
312
    end
313
    return dest
33,494,907✔
314
end
315

316
"""
317
    unsafe_copyto!(dest::Array, do, src::Array, so, N)
318

319
Copy `N` elements from a source array to a destination, starting at the linear index `so` in the
320
source and `do` in the destination (1-indexed).
321

322
The `unsafe` prefix on this function indicates that no validation is performed to ensure
323
that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
324
the same manner as C.
325
"""
326
function unsafe_copyto!(dest::Array{T}, doffs, src::Array{T}, soffs, n) where T
4,050,062✔
327
    t1 = @_gc_preserve_begin dest
171,821,331✔
328
    t2 = @_gc_preserve_begin src
171,821,331✔
329
    destp = pointer(dest, doffs)
171,821,331✔
330
    srcp = pointer(src, soffs)
171,821,342✔
331
    if !allocatedinline(T)
4,045,082✔
332
        ccall(:jl_array_ptr_copy, Cvoid, (Any, Ptr{Cvoid}, Any, Ptr{Cvoid}, Int),
71,172,949✔
333
              dest, destp, src, srcp, n)
334
    elseif isbitstype(T)
2,017,617✔
335
        memmove(destp, srcp, n * aligned_sizeof(T))
72,668,095✔
336
    elseif isbitsunion(T)
6,331✔
337
        memmove(destp, srcp, n * aligned_sizeof(T))
889✔
338
        # copy selector bytes
339
        memmove(
889✔
340
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), dest) + doffs - 1,
341
              ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), src) + soffs - 1,
342
              n)
343
    else
344
        _unsafe_copyto!(dest, doffs, src, soffs, n)
27,979,409✔
345
    end
346
    @_gc_preserve_end t2
171,821,331✔
347
    @_gc_preserve_end t1
171,821,331✔
348
    return dest
74,702,421✔
349
end
350

351
unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n) =
5,515,596✔
352
    _unsafe_copyto!(dest, doffs, src, soffs, n)
353

354
"""
355
    copyto!(dest, do, src, so, N)
356

357
Copy `N` elements from collection `src` starting at the linear index `so`, to array `dest` starting at
358
the index `do`. Return `dest`.
359
"""
360
function copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
40,382✔
361
    return _copyto_impl!(dest, doffs, src, soffs, n)
11,008,458✔
362
end
363

364
# this is only needed to avoid possible ambiguities with methods added in some packages
365
function copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where T
1,156,491✔
366
    return _copyto_impl!(dest, doffs, src, soffs, n)
226,534,173✔
367
end
368

369
function _copyto_impl!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
169,866,672✔
370
    n == 0 && return dest
204,076,589✔
371
    n > 0 || _throw_argerror("Number of elements to copy must be nonnegative.")
172,458,019✔
372
    @boundscheck checkbounds(dest, doffs:doffs+n-1)
172,458,038✔
373
    @boundscheck checkbounds(src, soffs:soffs+n-1)
172,457,999✔
374
    unsafe_copyto!(dest, doffs, src, soffs, n)
172,457,993✔
375
    return dest
172,457,752✔
376
end
377

378
# Outlining this because otherwise a catastrophic inference slowdown
379
# occurs, see discussion in #27874.
380
# It is also mitigated by using a constant string.
381
_throw_argerror(s) = (@noinline; throw(ArgumentError(s)))
4,132✔
382

383
copyto!(dest::Array, src::Array) = copyto!(dest, 1, src, 1, length(src))
10,977,595✔
384

385
# also to avoid ambiguities in packages
386
copyto!(dest::Array{T}, src::Array{T}) where {T} = copyto!(dest, 1, src, 1, length(src))
89,843,280✔
387

388
# N.B: The generic definition in multidimensional.jl covers, this, this is just here
389
# for bootstrapping purposes.
390
function fill!(dest::Array{T}, x) where T
127,273✔
391
    xT = x isa T ? x : convert(T, x)::T
127,222✔
392
    for i in eachindex(dest)
1,006,420,537✔
393
        @inbounds dest[i] = xT
2,147,483,647✔
394
    end
2,147,483,647✔
395
    return dest
732,408,156✔
396
end
397

398
"""
399
    copy(x)
400

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

405
See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref).
406
"""
407
copy
408

409
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
163,790,491✔
410

411
## Constructors ##
412

413
similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
69,588✔
414
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
4,172✔
415
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
9,487✔
416
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))
9,916✔
417
similar(a::Array{T}, m::Int) where {T}              = Vector{T}(undef, m)
1,789,621✔
418
similar(a::Array, T::Type, dims::Dims{N}) where {N} = Array{T,N}(undef, dims)
62,985,535✔
419
similar(a::Array{T}, dims::Dims{N}) where {T,N}     = Array{T,N}(undef, dims)
457✔
420

421
# T[x...] constructs Array{T,1}
422
"""
423
    getindex(type[, elements...])
424

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

428
# Examples
429
```jldoctest
430
julia> Int8[1, 2, 3]
431
3-element Vector{Int8}:
432
 1
433
 2
434
 3
435

436
julia> getindex(Int8, 1, 2, 3)
437
3-element Vector{Int8}:
438
 1
439
 2
440
 3
441
```
442
"""
443
function getindex(::Type{T}, vals...) where T
310,238✔
444
    @inline
119,377✔
445
    @_effect_free_terminates_locally_meta
119,377✔
446
    a = Vector{T}(undef, length(vals))
1,198,967,845✔
447
    if vals isa NTuple
119,530✔
448
        @_safeindex for i in 1:length(vals)
67,564✔
449
            a[i] = vals[i]
42,892,867✔
450
        end
185,944✔
451
    else
452
        # use afoldl to avoid type instability inside loop
453
        afoldl(1, vals...) do i, v
59,572✔
454
            @inbounds a[i] = v
126,918✔
455
            return i + 1
125,688✔
456
        end
457
    end
458
    return a
122,590✔
459
end
460

461
function getindex(::Type{Any}, @nospecialize vals...)
23,311,567✔
462
    @_effect_free_terminates_locally_meta
32,684✔
463
    a = Vector{Any}(undef, length(vals))
54,066,926✔
464
    @_safeindex for i = 1:length(vals)
46,477,423✔
465
        a[i] = vals[i]
101,687,617✔
466
    end
118,145,125✔
467
    return a
23,310,189✔
468
end
469
getindex(::Type{Any}) = Vector{Any}()
34,700,545✔
470

471
function fill!(a::Union{Array{UInt8}, Array{Int8}}, x::Integer)
11,620✔
472
    t = @_gc_preserve_begin a
13,832,270✔
473
    p = unsafe_convert(Ptr{Cvoid}, a)
13,832,270✔
474
    memset(p, x isa eltype(a) ? x : convert(eltype(a), x), length(a))
13,832,273✔
475
    @_gc_preserve_end t
13,832,267✔
476
    return a
13,832,267✔
477
end
478

479
to_dim(d::Integer) = d
×
480
to_dim(d::OneTo) = last(d)
376✔
481

482
"""
483
    fill(value, dims::Tuple)
484
    fill(value, dims...)
485

486
Create an array of size `dims` with every location set to `value`.
487

488
For example, `fill(1.0, (5,5))` returns a 5×5 array of floats,
489
with `1.0` in every location of the array.
490

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

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

504
```jldoctest
505
julia> v = fill([], 3)
506
3-element Vector{Vector{Any}}:
507
 []
508
 []
509
 []
510

511
julia> v[1] === v[2] === v[3]
512
true
513

514
julia> value = v[1]
515
Any[]
516

517
julia> push!(value, 867_5309)
518
1-element Vector{Any}:
519
 8675309
520

521
julia> v
522
3-element Vector{Vector{Any}}:
523
 [8675309]
524
 [8675309]
525
 [8675309]
526
```
527

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

531
```jldoctest
532
julia> v2 = [[] for _ in 1:3]
533
3-element Vector{Vector{Any}}:
534
 []
535
 []
536
 []
537

538
julia> v2[1] === v2[2] === v2[3]
539
false
540

541
julia> push!(v2[1], 8675309)
542
1-element Vector{Any}:
543
 8675309
544

545
julia> v2
546
3-element Vector{Vector{Any}}:
547
 [8675309]
548
 []
549
 []
550
```
551

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

554
# Examples
555
```jldoctest
556
julia> fill(1.0, (2,3))
557
2×3 Matrix{Float64}:
558
 1.0  1.0  1.0
559
 1.0  1.0  1.0
560

561
julia> fill(42)
562
0-dimensional Array{Int64, 0}:
563
42
564

565
julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector
566
2-element Vector{Vector{Float64}}:
567
 [0.0, 0.0]
568
 [0.0, 0.0]
569

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

572
julia> A # both A[1] and A[2] are the very same vector
573
2-element Vector{Vector{Float64}}:
574
 [42.0, 0.0]
575
 [42.0, 0.0]
576
```
577
"""
578
function fill end
579

580
fill(v, dims::DimOrInd...) = fill(v, dims)
2,147,483,647✔
581
fill(v, dims::NTuple{N, Union{Integer, OneTo}}) where {N} = fill(v, map(to_dim, dims))
×
582
fill(v, dims::NTuple{N, Integer}) where {N} = (a=Array{typeof(v),N}(undef, dims); fill!(a, v); a)
2,147,483,647✔
583
fill(v, dims::Tuple{}) = (a=Array{typeof(v),0}(undef, dims); fill!(a, v); a)
393✔
584

585
"""
586
    zeros([T=Float64,] dims::Tuple)
587
    zeros([T=Float64,] dims...)
588

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

592
# Examples
593
```jldoctest
594
julia> zeros(1)
595
1-element Vector{Float64}:
596
 0.0
597

598
julia> zeros(Int8, 2, 3)
599
2×3 Matrix{Int8}:
600
 0  0  0
601
 0  0  0
602
```
603
"""
604
function zeros end
605

606
"""
607
    ones([T=Float64,] dims::Tuple)
608
    ones([T=Float64,] dims...)
609

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

613
# Examples
614
```jldoctest
615
julia> ones(1,2)
616
1×2 Matrix{Float64}:
617
 1.0  1.0
618

619
julia> ones(ComplexF64, 2, 3)
620
2×3 Matrix{ComplexF64}:
621
 1.0+0.0im  1.0+0.0im  1.0+0.0im
622
 1.0+0.0im  1.0+0.0im  1.0+0.0im
623
```
624
"""
625
function ones end
626

627
for (fname, felt) in ((:zeros, :zero), (:ones, :one))
628
    @eval begin
629
        $fname(dims::DimOrInd...) = $fname(dims)
441,782✔
630
        $fname(::Type{T}, dims::DimOrInd...) where {T} = $fname(T, dims)
710,764,203✔
631
        $fname(dims::Tuple{Vararg{DimOrInd}}) = $fname(Float64, dims)
482,342✔
632
        $fname(::Type{T}, dims::NTuple{N, Union{Integer, OneTo}}) where {T,N} = $fname(T, map(to_dim, dims))
1,625✔
633
        function $fname(::Type{T}, dims::NTuple{N, Integer}) where {T,N}
31,999✔
634
            a = Array{T,N}(undef, dims)
94,450,306✔
635
            fill!(a, $felt(T))
1,117,577,288✔
636
            return a
94,450,306✔
637
        end
638
        function $fname(::Type{T}, dims::Tuple{}) where {T}
20✔
639
            a = Array{T}(undef)
20✔
640
            fill!(a, $felt(T))
20✔
641
            return a
20✔
642
        end
643
    end
644
end
645

646
function _one(unit::T, x::AbstractMatrix) where T
158✔
647
    require_one_based_indexing(x)
158✔
648
    m,n = size(x)
158✔
649
    m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
158✔
650
    # Matrix{T}(I, m, m)
651
    I = zeros(T, m, m)
3,765✔
652
    for i in 1:m
316✔
653
        I[i,i] = unit
649✔
654
    end
1,140✔
655
    I
158✔
656
end
657

658
one(x::AbstractMatrix{T}) where {T} = _one(one(T), x)
131✔
659
oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)
31✔
660

661
## Conversions ##
662

663
convert(::Type{T}, a::AbstractArray) where {T<:Array} = a isa T ? a : T(a)::T
352,820✔
664

665
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
64✔
666

667
## Constructors ##
668

669
if nameof(@__MODULE__) === :Base  # avoid method overwrite
670
# constructors should make copies
671
Array{T,N}(x::AbstractArray{S,N})         where {T,N,S} = copyto_axcheck!(Array{T,N}(undef, size(x)), x)
352,156✔
672
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copyto_axcheck!(similar(A,T), A)
8,663✔
673
end
674

675
## copying iterators to containers
676

677
"""
678
    collect(element_type, collection)
679

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

683
# Examples
684
```jldoctest
685
julia> collect(Float64, 1:2:5)
686
3-element Vector{Float64}:
687
 1.0
688
 3.0
689
 5.0
690
```
691
"""
692
collect(::Type{T}, itr) where {T} = _collect(T, itr, IteratorSize(itr))
30,468,038✔
693

694
_collect(::Type{T}, itr, isz::Union{HasLength,HasShape}) where {T} =
10,951,520✔
695
    copyto!(_array_for(T, isz, _similar_shape(itr, isz)), itr)
696
function _collect(::Type{T}, itr, isz::SizeUnknown) where T
19,516,518✔
697
    a = Vector{T}()
19,516,518✔
698
    for x in itr
33,558,629✔
699
        push!(a, x)
63,212,618✔
700
    end
112,383,124✔
701
    return a
19,516,518✔
702
end
703

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

707
_similar_shape(itr, ::SizeUnknown) = nothing
1✔
708
_similar_shape(itr, ::HasLength) = length(itr)::Integer
32,349,623✔
709
_similar_shape(itr, ::HasShape) = axes(itr)
447,797,965✔
710

711
_similar_for(c::AbstractArray, ::Type{T}, itr, ::SizeUnknown, ::Nothing) where {T} =
1,089,610✔
712
    similar(c, T, 0)
713
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasLength, len::Integer) where {T} =
3,948,306✔
714
    similar(c, T, len)
715
_similar_for(c::AbstractArray, ::Type{T}, itr, ::HasShape, axs) where {T} =
145,942✔
716
    similar(c, T, axs)
717

718
# make a collection appropriate for collecting `itr::Generator`
719
_array_for(::Type{T}, ::SizeUnknown, ::Nothing) where {T} = Vector{T}(undef, 0)
339✔
720
_array_for(::Type{T}, ::HasLength, len::Integer) where {T} = Vector{T}(undef, Int(len))
25,605,491✔
721
_array_for(::Type{T}, ::HasShape{N}, axs) where {T,N} = similar(Array{T,N}, axs)
447,851,628✔
722

723
# used by syntax lowering for simple typed comprehensions
724
_array_for(::Type{T}, itr, isz) where {T} = _array_for(T, isz, _similar_shape(itr, isz))
469,988,050✔
725

726

727
"""
728
    collect(collection)
729

730
Return an `Array` of all items in a collection or iterator. For dictionaries, returns
731
`Vector{Pair{KeyType, ValType}}`. If the argument is array-like or is an iterator with the
732
[`HasShape`](@ref IteratorSize) trait, the result will have the same shape
733
and number of dimensions as the argument.
734

735
Used by comprehensions to turn a generator into an `Array`.
736

737
# Examples
738
```jldoctest
739
julia> collect(1:2:13)
740
7-element Vector{Int64}:
741
  1
742
  3
743
  5
744
  7
745
  9
746
 11
747
 13
748

749
julia> [x^2 for x in 1:8 if isodd(x)]
750
4-element Vector{Int64}:
751
  1
752
  9
753
 25
754
 49
755
```
756
"""
757
collect(itr) = _collect(1:1 #= Array =#, itr, IteratorEltype(itr), IteratorSize(itr))
5,339,403✔
758

759
collect(A::AbstractArray) = _collect_indices(axes(A), A)
142,909✔
760

761
collect_similar(cont, itr) = _collect(cont, itr, IteratorEltype(itr), IteratorSize(itr))
145,332✔
762

763
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
4,249,983✔
764
    copyto!(_similar_for(cont, eltype(itr), itr, isz, _similar_shape(itr, isz)), itr)
765

766
function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
1,089,576✔
767
    a = _similar_for(cont, eltype(itr), itr, isz, nothing)
1,089,576✔
768
    for x in itr
2,178,125✔
769
        push!(a,x)
9,027,001✔
770
    end
15,357,490✔
771
    return a
1,089,575✔
772
end
773

774
_collect_indices(::Tuple{}, A) = copyto!(Array{eltype(A),0}(undef), A)
26✔
775
_collect_indices(indsA::Tuple{Vararg{OneTo}}, A) =
189,011✔
776
    copyto!(Array{eltype(A)}(undef, length.(indsA)), A)
777
function _collect_indices(indsA, A)
121✔
778
    B = Array{eltype(A)}(undef, length.(indsA))
121✔
779
    copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA))
121✔
780
end
781

782
# NOTE: this function is not meant to be called, only inferred, for the
783
# purpose of bounding the types of values generated by an iterator.
784
function _iterator_upper_bound(itr)
2✔
785
    x = iterate(itr)
×
786
    while x !== nothing
×
787
        val = getfield(x, 1)
×
788
        if inferencebarrier(nothing)
×
789
            return val
×
790
        end
791
        x = iterate(itr, getfield(x, 2))
×
792
    end
×
793
    throw(nothing)
2✔
794
end
795

796
# define this as a macro so that the call to Core.Compiler
797
# gets inlined into the caller before recursion detection
798
# gets a chance to see it, so that recursive calls to the caller
799
# don't trigger the inference limiter
800
if isdefined(Core, :Compiler)
801
    macro default_eltype(itr)
1✔
802
        I = esc(itr)
1✔
803
        return quote
1✔
804
            if $I isa Generator && ($I).f isa Type
216,280✔
805
                T = ($I).f
13,239✔
806
            else
807
                T = Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)})
203,041✔
808
            end
809
            promote_typejoin_union(T)
216,330✔
810
        end
811
    end
812
else
813
    macro default_eltype(itr)
814
        I = esc(itr)
815
        return quote
816
            if $I isa Generator && ($I).f isa Type
817
                promote_typejoin_union($I.f)
818
            else
819
                Any
820
            end
821
        end
822
    end
823
end
824

825
function collect(itr::Generator)
576,653✔
826
    isz = IteratorSize(itr.iter)
70,641✔
827
    et = @default_eltype(itr)
×
828
    if isa(isz, SizeUnknown)
70,641✔
829
        return grow_to!(Vector{et}(), itr)
87,332✔
830
    else
831
        shp = _similar_shape(itr, isz)
489,997✔
832
        y = iterate(itr)
968,331✔
833
        if y === nothing
489,699✔
834
            return _array_for(et, isz, shp)
841✔
835
        end
836
        v1, st = y
69,206✔
837
        dest = _array_for(typeof(v1), isz, shp)
489,006✔
838
        # The typeassert gives inference a helping hand on the element type and dimensionality
839
        # (work-around for #28382)
840
        et′ = et <: Type ? Type : et
69,206✔
841
        RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
69,294✔
842
        collect_to_with_first!(dest, v1, itr, st)::RT
10,482,909✔
843
    end
844
end
845

846
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
34✔
847
    grow_to!(_similar_for(c, @default_eltype(itr), itr, isz, nothing), itr)
848

849
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
144,794✔
850
    et = @default_eltype(itr)
131,507✔
851
    shp = _similar_shape(itr, isz)
144,794✔
852
    y = iterate(itr)
287,898✔
853
    if y === nothing
144,792✔
854
        return _similar_for(c, et, itr, isz, shp)
1,297✔
855
    end
856
    v1, st = y
130,446✔
857
    dest = _similar_for(c, typeof(v1), itr, isz, shp)
143,510✔
858
    # The typeassert gives inference a helping hand on the element type and dimensionality
859
    # (work-around for #28382)
860
    et′ = et <: Type ? Type : et
130,393✔
861
    RT = dest isa AbstractArray ? AbstractArray{<:et′, ndims(dest)} : Any
130,405✔
862
    collect_to_with_first!(dest, v1, itr, st)::RT
144,061✔
863
end
864

865
function collect_to_with_first!(dest::AbstractArray, v1, itr, st)
199,817✔
866
    i1 = first(LinearIndices(dest))
199,599✔
867
    dest[i1] = v1
632,399✔
868
    return collect_to!(dest, itr, i1+1, st)
55,124,156✔
869
end
870

871
function collect_to_with_first!(dest, v1, itr, st)
×
872
    push!(dest, v1)
×
873
    return grow_to!(dest, itr, st)
×
874
end
875

876
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
397✔
877
    @inline
394✔
878
    new = similar(dest, promote_typejoin(T, typeof(el)))
401✔
879
    f = first(LinearIndices(dest))
394✔
880
    copyto!(new, first(LinearIndices(new)), dest, f, i-f)
789✔
881
    @inbounds new[i] = el
397✔
882
    return new
397✔
883
end
884

885
function collect_to!(dest::AbstractArray{T}, itr, offs, st) where T
238,689✔
886
    # collect to dest array, checking the type of each result. if a result does not
887
    # match, widen the result type and re-dispatch.
888
    i = offs
199,996✔
889
    while true
62,731,750✔
890
        y = iterate(itr, st)
124,829,655✔
891
        y === nothing && break
62,731,740✔
892
        el, st = y
61,633,618✔
893
        if el isa T
61,632,173✔
894
            @inbounds dest[i] = el
62,105,674✔
895
            i += 1
62,098,954✔
896
        else
897
            new = setindex_widen_up_to(dest, el, i)
524✔
898
            return collect_to!(new, itr, i+1, st)
397✔
899
        end
900
    end
62,098,954✔
901
    return dest
632,389✔
902
end
903

904
function grow_to!(dest, itr)
1,175✔
905
    y = iterate(itr)
1,460✔
906
    y === nothing && return dest
1,175✔
907
    dest2 = empty(dest, typeof(y[1]))
305✔
908
    push!(dest2, y[1])
329✔
909
    grow_to!(dest2, itr, y[2])
290✔
910
end
911

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

925
function grow_to!(dest, itr, st)
342✔
926
    T = eltype(dest)
237✔
927
    y = iterate(itr, st)
622✔
928
    while y !== nothing
4,092✔
929
        el, st = y
2,476✔
930
        if el isa T
2,476✔
931
            push!(dest, el)
3,752✔
932
        else
933
            new = push_widen(dest, el)
54✔
934
            return grow_to!(new, itr, st)
52✔
935
        end
936
        y = iterate(itr, st)
5,781✔
937
    end
3,750✔
938
    return dest
290✔
939
end
940

941
## Iteration ##
942

943
iterate(A::Array, i=1) = (@inline; (i % UInt) - 1 < length(A) ? (@inbounds A[i], i + 1) : nothing)
2,147,483,647✔
944

945
## Indexing: getindex ##
946

947
"""
948
    getindex(collection, key...)
949

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

953
See also [`get`](@ref), [`keys`](@ref), [`eachindex`](@ref).
954

955
# Examples
956
```jldoctest
957
julia> A = Dict("a" => 1, "b" => 2)
958
Dict{String, Int64} with 2 entries:
959
  "b" => 2
960
  "a" => 1
961

962
julia> getindex(A, "a")
963
1
964
```
965
"""
966
function getindex end
967

968
# Faster contiguous indexing using copyto! for AbstractUnitRange and Colon
969
function getindex(A::Array, I::AbstractUnitRange{<:Integer})
1,171,070✔
970
    @inline
866,052✔
971
    @boundscheck checkbounds(A, I)
62,577,101✔
972
    lI = length(I)
62,577,101✔
973
    X = similar(A, axes(I))
62,577,113✔
974
    if lI > 0
62,577,101✔
975
        copyto!(X, firstindex(X), A, first(I), lI)
66,128,592✔
976
    end
977
    return X
62,577,101✔
978
end
979

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

983
function getindex(A::Array, c::Colon)
4,900✔
984
    lI = length(A)
1,783,838✔
985
    X = similar(A, lI)
1,783,838✔
986
    if lI > 0
1,783,838✔
987
        unsafe_copyto!(X, 1, A, 1, lI)
1,783,836✔
988
    end
989
    return X
1,783,838✔
990
end
991

992
# This is redundant with the abstract fallbacks, but needed for bootstrap
993
function getindex(A::Array{S}, I::AbstractRange{Int}) where S
3,169,012✔
994
    return S[ A[i] for i in I ]
13,053,133✔
995
end
996

997
## Indexing: setindex! ##
998

999
"""
1000
    setindex!(collection, value, key...)
1001

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

1005
# Examples
1006
```jldoctest
1007
julia> a = Dict("a"=>1)
1008
Dict{String, Int64} with 1 entry:
1009
  "a" => 1
1010

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

1019
@eval setindex!(A::Array{T}, x, i1::Int) where {T} =
2,147,483,647✔
1020
    arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1)
1021
@eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
41,936,199✔
1022
    (@inline; arrayset($(Expr(:boundscheck)), A, x isa T ? x : convert(T,x)::T, i1, i2, I...))
42,549,569✔
1023

1024
__inbounds_setindex!(A::Array{T}, x, i1::Int) where {T} =
1,742,142,948✔
1025
    arrayset(false, A, convert(T,x)::T, i1)
1026
__inbounds_setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} =
×
1027
    (@inline; arrayset(false, A, convert(T,x)::T, i1, i2, I...))
×
1028

1029
# This is redundant with the abstract fallbacks but needed and helpful for bootstrap
1030
function setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int})
813,110✔
1031
    @_propagate_inbounds_meta
813,070✔
1032
    @boundscheck setindex_shape_check(X, length(I))
6,602,159✔
1033
    require_one_based_indexing(X)
813,070✔
1034
    X′ = unalias(A, X)
818,420✔
1035
    I′ = unalias(A, I)
813,502✔
1036
    count = 1
813,070✔
1037
    for i in I′
12,358,547✔
1038
        @inbounds x = X′[count]
17,115,039✔
1039
        A[i] = x
17,117,122✔
1040
        count += 1
17,115,039✔
1041
    end
28,426,170✔
1042
    return A
6,602,159✔
1043
end
1044

1045
# Faster contiguous setindex! with copyto!
1046
function setindex!(A::Array{T}, X::Array{T}, I::AbstractUnitRange{Int}) where T
1,007,816✔
1047
    @inline
1,007,336✔
1048
    @boundscheck checkbounds(A, I)
1,008,172✔
1049
    lI = length(I)
1,008,172✔
1050
    @boundscheck setindex_shape_check(X, lI)
1,008,172✔
1051
    if lI > 0
1,008,172✔
1052
        unsafe_copyto!(A, first(I), X, 1, lI)
1,008,132✔
1053
    end
1054
    return A
1,008,172✔
1055
end
1056
function setindex!(A::Array{T}, X::Array{T}, c::Colon) where T
46✔
1057
    @inline
46✔
1058
    lI = length(A)
46✔
1059
    @boundscheck setindex_shape_check(X, lI)
46✔
1060
    if lI > 0
46✔
1061
        unsafe_copyto!(A, 1, X, 1, lI)
46✔
1062
    end
1063
    return A
46✔
1064
end
1065

1066
# efficiently grow an array
1067

1068
_growbeg!(a::Vector, delta::Integer) =
5,132,964✔
1069
    ccall(:jl_array_grow_beg, Cvoid, (Any, UInt), a, delta)
1070
_growend!(a::Vector, delta::Integer) =
2,146,715,375✔
1071
    ccall(:jl_array_grow_end, Cvoid, (Any, UInt), a, delta)
1072
_growat!(a::Vector, i::Integer, delta::Integer) =
76,371,219✔
1073
    ccall(:jl_array_grow_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1074

1075
# efficiently delete part of an array
1076

1077
_deletebeg!(a::Vector, delta::Integer) =
26,208,003✔
1078
    ccall(:jl_array_del_beg, Cvoid, (Any, UInt), a, delta)
1079
_deleteend!(a::Vector, delta::Integer) =
868,614,371✔
1080
    ccall(:jl_array_del_end, Cvoid, (Any, UInt), a, delta)
1081
_deleteat!(a::Vector, i::Integer, delta::Integer) =
5,029,387✔
1082
    ccall(:jl_array_del_at, Cvoid, (Any, Int, UInt), a, i - 1, delta)
1083

1084
## Dequeue functionality ##
1085

1086
"""
1087
    push!(collection, items...) -> collection
1088

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

1092
# Examples
1093
```jldoctest
1094
julia> push!([1, 2, 3], 4, 5, 6)
1095
6-element Vector{Int64}:
1096
 1
1097
 2
1098
 3
1099
 4
1100
 5
1101
 6
1102
```
1103

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

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

1110
See also [`pushfirst!`](@ref).
1111
"""
1112
function push! end
1113

1114
function push!(a::Vector{T}, item) where T
3,160,852✔
1115
    # convert first so we don't grow the array if the assignment won't work
1116
    itemT = item isa T ? item : convert(T, item)::T
30,537,424✔
1117
    _growend!(a, 1)
1,418,754,545✔
1118
    @_safeindex a[length(a)] = itemT
1,418,754,545✔
1119
    return a
16,653,239✔
1120
end
1121

1122
# specialize and optimize the single argument case
1123
function push!(a::Vector{Any}, @nospecialize x)
3,181,750✔
1124
    _growend!(a, 1)
108,672,250✔
1125
    @_safeindex a[length(a)] = x
108,672,248✔
1126
    return a
2,923,901✔
1127
end
1128
function push!(a::Vector{Any}, @nospecialize x...)
949,934✔
1129
    @_terminates_locally_meta
2✔
1130
    na = length(a)
949,934✔
1131
    nx = length(x)
2✔
1132
    _growend!(a, nx)
949,934✔
1133
    @_safeindex for i = 1:nx
1,899,866✔
1134
        a[na+i] = x[i]
2,744,681✔
1135
    end
2,849,806✔
1136
    return a
949,934✔
1137
end
1138

1139
"""
1140
    append!(collection, collections...) -> collection.
1141

1142
For an ordered container `collection`, add the elements of each `collections`
1143
to the end of it.
1144

1145
!!! compat "Julia 1.6"
1146
    Specifying multiple collections to be appended requires at least Julia 1.6.
1147

1148
# Examples
1149
```jldoctest
1150
julia> append!([1], [2, 3])
1151
3-element Vector{Int64}:
1152
 1
1153
 2
1154
 3
1155

1156
julia> append!([1, 2, 3], [4, 5], [6])
1157
6-element Vector{Int64}:
1158
 1
1159
 2
1160
 3
1161
 4
1162
 5
1163
 6
1164
```
1165

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

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

1172
See also [`vcat`](@ref) for vectors, [`union!`](@ref) for sets,
1173
and [`prepend!`](@ref) and [`pushfirst!`](@ref) for the opposite order.
1174
"""
1175
function append! end
1176

1177
function append!(a::Vector, items::AbstractVector)
6,943,938✔
1178
    itemindices = eachindex(items)
63,991,973✔
1179
    n = length(itemindices)
44,616✔
1180
    _growend!(a, n)
63,991,973✔
1181
    copyto!(a, length(a)-n+1, items, first(itemindices), n)
70,084,078✔
1182
    return a
63,991,973✔
1183
end
1184

1185
append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
71,718,399✔
1186
push!(a::AbstractVector, iter...) = append!(a, iter)
12,275,916✔
1187

1188
append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
78✔
1189

1190
function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
30,906,623✔
1191
    @_terminates_locally_meta
12,273,861✔
1192
    n = length(a)
30,906,623✔
1193
    i = lastindex(a)
30,906,623✔
1194
    resize!(a, n+Int(length(iter))::Int)
42,526,698✔
1195
    for (i, item) in zip(i+1:lastindex(a), iter)
50,193,171✔
1196
        if isa(a, Vector) # give better effects for builtin vectors
24,552,098✔
1197
            @_safeindex a[i] = item
59,146,483✔
1198
        else
1199
            a[i] = item
×
1200
        end
1201
    end
99,003,042✔
1202
    a
30,906,623✔
1203
end
1204
function _append!(a::AbstractVector, ::IteratorSize, iter)
40,811,775✔
1205
    for item in iter
40,811,777✔
1206
        push!(a, item)
41,806,239✔
1207
    end
41,806,244✔
1208
    a
40,811,775✔
1209
end
1210

1211
"""
1212
    prepend!(a::Vector, collections...) -> collection
1213

1214
Insert the elements of each `collections` to the beginning of `a`.
1215

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

1219
!!! compat "Julia 1.6"
1220
    Specifying multiple collections to be prepended requires at least Julia 1.6.
1221

1222
# Examples
1223
```jldoctest
1224
julia> prepend!([3], [1, 2])
1225
3-element Vector{Int64}:
1226
 1
1227
 2
1228
 3
1229

1230
julia> prepend!([6], [1, 2], [3, 4, 5])
1231
6-element Vector{Int64}:
1232
 1
1233
 2
1234
 3
1235
 4
1236
 5
1237
 6
1238
```
1239
"""
1240
function prepend! end
1241

1242
function prepend!(a::Vector, items::AbstractVector)
5,274✔
1243
    itemindices = eachindex(items)
5,274✔
1244
    n = length(itemindices)
5,232✔
1245
    _growbeg!(a, n)
5,274✔
1246
    if a === items
5,274✔
1247
        copyto!(a, 1, items, n+1, n)
1✔
1248
    else
1249
        copyto!(a, 1, items, first(itemindices), n)
5,969✔
1250
    end
1251
    return a
5,274✔
1252
end
1253

1254
prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
13✔
1255
pushfirst!(a::Vector, iter...) = prepend!(a, iter)
7✔
1256

1257
prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
7✔
1258

1259
function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
7✔
1260
    @_terminates_locally_meta
7✔
1261
    require_one_based_indexing(a)
7✔
1262
    n = length(iter)
7✔
1263
    _growbeg!(a, n)
7✔
1264
    i = 0
7✔
1265
    for item in iter
7✔
1266
        @_safeindex a[i += 1] = item
13✔
1267
    end
18✔
1268
    a
7✔
1269
end
1270
function _prepend!(a::Vector, ::IteratorSize, iter)
2✔
1271
    n = 0
2✔
1272
    for item in iter
3✔
1273
        n += 1
5✔
1274
        pushfirst!(a, item)
5✔
1275
    end
9✔
1276
    reverse!(a, 1, n)
2✔
1277
    a
2✔
1278
end
1279

1280
"""
1281
    resize!(a::Vector, n::Integer) -> Vector
1282

1283
Resize `a` to contain `n` elements. If `n` is smaller than the current collection
1284
length, the first `n` elements will be retained. If `n` is larger, the new elements are not
1285
guaranteed to be initialized.
1286

1287
# Examples
1288
```jldoctest
1289
julia> resize!([6, 5, 4, 3, 2, 1], 3)
1290
3-element Vector{Int64}:
1291
 6
1292
 5
1293
 4
1294

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

1297
julia> length(a)
1298
8
1299

1300
julia> a[1:6]
1301
6-element Vector{Int64}:
1302
 6
1303
 5
1304
 4
1305
 3
1306
 2
1307
 1
1308
```
1309
"""
1310
function resize!(a::Vector, nl::Integer)
18,344,754✔
1311
    l = length(a)
969,406,460✔
1312
    if nl > l
969,406,460✔
1313
        _growend!(a, nl-l)
396,567,653✔
1314
    elseif nl != l
572,838,807✔
1315
        if nl < 0
73,784,377✔
1316
            _throw_argerror("new length must be ≥ 0")
2✔
1317
        end
1318
        _deleteend!(a, l-nl)
281,854,219✔
1319
    end
1320
    return a
969,406,458✔
1321
end
1322

1323
"""
1324
    sizehint!(s, n) -> s
1325

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

1331
See also [`resize!`](@ref).
1332

1333
# Notes on the performance model
1334

1335
For types that support `sizehint!`,
1336

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

1341
2. `sizehint!` may control this preallocation. Again, it typically does this for types in
1342
   `Base`.
1343

1344
3. `empty!` is nearly costless (and O(1)) for types that support this kind of preallocation.
1345
"""
1346
function sizehint! end
1347

1348
function sizehint!(a::Vector, sz::Integer)
455,991✔
1349
    ccall(:jl_array_sizehint, Cvoid, (Any, UInt), a, sz)
529,644✔
1350
    a
509,946✔
1351
end
1352

1353
"""
1354
    pop!(collection) -> item
1355

1356
Remove an item in `collection` and return it. If `collection` is an
1357
ordered container, the last item is returned; for unordered containers,
1358
an arbitrary element is returned.
1359

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

1362
# Examples
1363
```jldoctest
1364
julia> A=[1, 2, 3]
1365
3-element Vector{Int64}:
1366
 1
1367
 2
1368
 3
1369

1370
julia> pop!(A)
1371
3
1372

1373
julia> A
1374
2-element Vector{Int64}:
1375
 1
1376
 2
1377

1378
julia> S = Set([1, 2])
1379
Set{Int64} with 2 elements:
1380
  2
1381
  1
1382

1383
julia> pop!(S)
1384
2
1385

1386
julia> S
1387
Set{Int64} with 1 element:
1388
  1
1389

1390
julia> pop!(Dict(1=>2))
1391
1 => 2
1392
```
1393
"""
1394
function pop!(a::Vector)
78,392✔
1395
    if isempty(a)
510,737,687✔
1396
        _throw_argerror("array must be non-empty")
1✔
1397
    end
1398
    item = a[end]
510,737,686✔
1399
    _deleteend!(a, 1)
510,737,686✔
1400
    return item
510,737,686✔
1401
end
1402

1403
"""
1404
    popat!(a::Vector, i::Integer, [default])
1405

1406
Remove the item at the given `i` and return it. Subsequent items
1407
are shifted to fill the resulting gap.
1408
When `i` is not a valid index for `a`, return `default`, or throw an error if
1409
`default` is not specified.
1410

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

1413
!!! compat "Julia 1.5"
1414
    This function is available as of Julia 1.5.
1415

1416
# Examples
1417
```jldoctest
1418
julia> a = [4, 3, 2, 1]; popat!(a, 2)
1419
3
1420

1421
julia> a
1422
3-element Vector{Int64}:
1423
 4
1424
 2
1425
 1
1426

1427
julia> popat!(a, 4, missing)
1428
missing
1429

1430
julia> popat!(a, 4)
1431
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
1432
[...]
1433
```
1434
"""
1435
function popat!(a::Vector, i::Integer)
7✔
1436
    x = a[i]
7✔
1437
    _deleteat!(a, i, 1)
4✔
1438
    x
4✔
1439
end
1440

1441
function popat!(a::Vector, i::Integer, default)
2✔
1442
    if 1 <= i <= length(a)
2✔
1443
        x = @inbounds a[i]
1✔
1444
        _deleteat!(a, i, 1)
1✔
1445
        x
1✔
1446
    else
1447
        default
1✔
1448
    end
1449
end
1450

1451
"""
1452
    pushfirst!(collection, items...) -> collection
1453

1454
Insert one or more `items` at the beginning of `collection`.
1455

1456
This function is called `unshift` in many other programming languages.
1457

1458
# Examples
1459
```jldoctest
1460
julia> pushfirst!([1, 2, 3, 4], 5, 6)
1461
6-element Vector{Int64}:
1462
 5
1463
 6
1464
 1
1465
 2
1466
 3
1467
 4
1468
```
1469
"""
1470
function pushfirst!(a::Vector{T}, item) where T
54,999✔
1471
    item = item isa T ? item : convert(T, item)::T
54,982✔
1472
    _growbeg!(a, 1)
4,086,142✔
1473
    @_safeindex a[1] = item
4,086,142✔
1474
    return a
54,999✔
1475
end
1476

1477
# specialize and optimize the single argument case
1478
function pushfirst!(a::Vector{Any}, @nospecialize x)
126✔
1479
    _growbeg!(a, 1)
757,287✔
1480
    @_safeindex a[1] = x
757,287✔
1481
    return a
124✔
1482
end
1483
function pushfirst!(a::Vector{Any}, @nospecialize x...)
774✔
1484
    @_terminates_locally_meta
2✔
1485
    na = length(a)
2✔
1486
    nx = length(x)
2✔
1487
    _growbeg!(a, nx)
774✔
1488
    @_safeindex for i = 1:nx
1,546✔
1489
        a[i] = x[i]
1,550✔
1490
    end
2,326✔
1491
    return a
774✔
1492
end
1493

1494
"""
1495
    popfirst!(collection) -> item
1496

1497
Remove the first `item` from `collection`.
1498

1499
This function is called `shift` in many other programming languages.
1500

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

1503
# Examples
1504
```jldoctest
1505
julia> A = [1, 2, 3, 4, 5, 6]
1506
6-element Vector{Int64}:
1507
 1
1508
 2
1509
 3
1510
 4
1511
 5
1512
 6
1513

1514
julia> popfirst!(A)
1515
1
1516

1517
julia> A
1518
5-element Vector{Int64}:
1519
 2
1520
 3
1521
 4
1522
 5
1523
 6
1524
```
1525
"""
1526
function popfirst!(a::Vector)
1,036,518✔
1527
    if isempty(a)
26,150,621✔
1528
        _throw_argerror("array must be non-empty")
1✔
1529
    end
1530
    item = a[1]
26,150,621✔
1531
    _deletebeg!(a, 1)
26,150,622✔
1532
    return item
26,150,620✔
1533
end
1534

1535
"""
1536
    insert!(a::Vector, index::Integer, item)
1537

1538
Insert an `item` into `a` at the given `index`. `index` is the index of `item` in
1539
the resulting `a`.
1540

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

1543
# Examples
1544
```jldoctest
1545
julia> insert!(Any[1:6;], 3, "here")
1546
7-element Vector{Any}:
1547
 1
1548
 2
1549
  "here"
1550
 3
1551
 4
1552
 5
1553
 6
1554
```
1555
"""
1556
function insert!(a::Array{T,1}, i::Integer, item) where T
213,342✔
1557
    # Throw convert error before changing the shape of the array
1558
    _item = item isa T ? item : convert(T, item)::T
213,336✔
1559
    _growat!(a, i, 1)
76,344,786✔
1560
    # _growat! already did bound check
1561
    @inbounds a[i] = _item
76,344,780✔
1562
    return a
213,336✔
1563
end
1564

1565
"""
1566
    deleteat!(a::Vector, i::Integer)
1567

1568
Remove the item at the given `i` and return the modified `a`. Subsequent items
1569
are shifted to fill the resulting gap.
1570

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

1573
# Examples
1574
```jldoctest
1575
julia> deleteat!([6, 5, 4, 3, 2, 1], 2)
1576
5-element Vector{Int64}:
1577
 6
1578
 4
1579
 3
1580
 2
1581
 1
1582
```
1583
"""
1584
function deleteat!(a::Vector, i::Integer)
16,712✔
1585
    i isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
16,712✔
1586
    _deleteat!(a, i, 1)
4,935,799✔
1587
    return a
16,706✔
1588
end
1589

1590
function deleteat!(a::Vector, r::AbstractUnitRange{<:Integer})
72,106✔
1591
    if eltype(r) === Bool
72,106✔
1592
        return invoke(deleteat!, Tuple{Vector, AbstractVector{Bool}}, a, r)
6✔
1593
    else
1594
        n = length(a)
72,100✔
1595
        f = first(r)
72,195✔
1596
        f isa Bool && depwarn("passing Bool as an index is deprecated", :deleteat!)
72,100✔
1597
        isempty(r) || _deleteat!(a, f, length(r))
160,876✔
1598
        return a
80,660✔
1599
    end
1600
end
1601

1602
"""
1603
    deleteat!(a::Vector, inds)
1604

1605
Remove the items at the indices given by `inds`, and return the modified `a`.
1606
Subsequent items are shifted to fill the resulting gap.
1607

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

1611
# Examples
1612
```jldoctest
1613
julia> deleteat!([6, 5, 4, 3, 2, 1], 1:2:5)
1614
3-element Vector{Int64}:
1615
 5
1616
 3
1617
 1
1618

1619
julia> deleteat!([6, 5, 4, 3, 2, 1], [true, false, true, false, true, false])
1620
3-element Vector{Int64}:
1621
 5
1622
 3
1623
 1
1624

1625
julia> deleteat!([6, 5, 4, 3, 2, 1], (2, 2))
1626
ERROR: ArgumentError: indices must be unique and sorted
1627
Stacktrace:
1628
[...]
1629
```
1630
"""
1631
deleteat!(a::Vector, inds) = _deleteat!(a, inds)
19✔
1632
deleteat!(a::Vector, inds::AbstractVector) = _deleteat!(a, to_indices(a, (inds,))[1])
90,146✔
1633

1634
struct Nowhere; end
1635
push!(::Nowhere, _) = nothing
1,490,967✔
1636
_growend!(::Nowhere, _) = nothing
×
1637

1638
@inline function _push_deleted!(dltd, a::Vector, ind)
1,490,969✔
1639
    if @inbounds isassigned(a, ind)
1,551,611✔
1640
        push!(dltd, @inbounds a[ind])
1,551,625✔
1641
    else
1642
        _growend!(dltd, 1)
1✔
1643
    end
1644
end
1645

1646
@inline function _copy_item!(a::Vector, p, q)
4,379,026✔
1647
    if @inbounds isassigned(a, q)
4,408,121✔
1648
        @inbounds a[p] = a[q]
4,408,141✔
1649
    else
1650
        _unsetindex!(a, p)
1✔
1651
    end
1652
end
1653

1654
function _deleteat!(a::Vector, inds, dltd=Nowhere())
125,867✔
1655
    n = length(a)
180,331✔
1656
    y = iterate(inds)
90,404✔
1657
    y === nothing && return a
90,166✔
1658
    (p, s) = y
35,470✔
1659
    checkbounds(a, p)
89,940✔
1660
    _push_deleted!(dltd, a, p)
89,933✔
1661
    q = p+1
89,928✔
1662
    while true
1,551,611✔
1663
        y = iterate(inds, s)
1,641,533✔
1664
        y === nothing && break
1,551,611✔
1665
        (i,s) = y
1,455,505✔
1666
        if !(q <= i <= n)
1,461,685✔
1667
            if i < q
2✔
1668
                _throw_argerror("indices must be unique and sorted")
1✔
1669
            else
1670
                throw(BoundsError())
1✔
1671
            end
1672
        end
1673
        while q < i
2,887,540✔
1674
            _copy_item!(a, p, q)
1,425,872✔
1675
            p += 1; q += 1
2,851,714✔
1676
        end
1,425,857✔
1677
        _push_deleted!(dltd, a, i)
1,461,694✔
1678
        q = i+1
1,461,683✔
1679
    end
1,461,683✔
1680
    while q <= n
3,029,996✔
1681
        _copy_item!(a, p, q)
2,940,077✔
1682
        p += 1; q += 1
5,880,140✔
1683
    end
2,940,070✔
1684
    _deleteend!(a, n-p+1)
89,926✔
1685
    return a
89,926✔
1686
end
1687

1688
# Simpler and more efficient version for logical indexing
1689
function deleteat!(a::Vector, inds::AbstractVector{Bool})
4,029✔
1690
    n = length(a)
4,029✔
1691
    length(inds) == n || throw(BoundsError(a, inds))
4,034✔
1692
    p = 1
4,024✔
1693
    for (q, i) in enumerate(inds)
8,047✔
1694
        _copy_item!(a, p, q)
42,194✔
1695
        p += !i
42,194✔
1696
    end
80,365✔
1697
    _deleteend!(a, n-p+1)
4,024✔
1698
    return a
4,024✔
1699
end
1700

1701
const _default_splice = []
1702

1703
"""
1704
    splice!(a::Vector, index::Integer, [replacement]) -> item
1705

1706
Remove the item at the given index, and return the removed item.
1707
Subsequent items are shifted left to fill the resulting gap.
1708
If specified, replacement values from an ordered
1709
collection will be spliced in place of the removed item.
1710

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

1713
# Examples
1714
```jldoctest
1715
julia> A = [6, 5, 4, 3, 2, 1]; splice!(A, 5)
1716
2
1717

1718
julia> A
1719
5-element Vector{Int64}:
1720
 6
1721
 5
1722
 4
1723
 3
1724
 1
1725

1726
julia> splice!(A, 5, -1)
1727
1
1728

1729
julia> A
1730
5-element Vector{Int64}:
1731
  6
1732
  5
1733
  4
1734
  3
1735
 -1
1736

1737
julia> splice!(A, 1, [-1, -2, -3])
1738
6
1739

1740
julia> A
1741
7-element Vector{Int64}:
1742
 -1
1743
 -2
1744
 -3
1745
  5
1746
  4
1747
  3
1748
 -1
1749
```
1750

1751
To insert `replacement` before an index `n` without removing any items, use
1752
`splice!(collection, n:n-1, replacement)`.
1753
"""
1754
function splice!(a::Vector, i::Integer, ins=_default_splice)
3,707✔
1755
    v = a[i]
3,718✔
1756
    m = length(ins)
3,429✔
1757
    if m == 0
3,429✔
1758
        _deleteat!(a, i, 1)
554✔
1759
    elseif m == 1
2,875✔
1760
        a[i] = only(ins)
266✔
1761
    else
1762
        _growat!(a, i, m-1)
2,609✔
1763
        k = 1
2,609✔
1764
        for x in ins
2,609✔
1765
            a[i+k-1] = x
333,212✔
1766
            k += 1
333,212✔
1767
        end
333,212✔
1768
    end
1769
    return v
3,429✔
1770
end
1771

1772
"""
1773
    splice!(a::Vector, indices, [replacement]) -> items
1774

1775
Remove items at specified indices, and return a collection containing
1776
the removed items.
1777
Subsequent items are shifted left to fill the resulting gaps.
1778
If specified, replacement values from an ordered collection will be spliced in
1779
place of the removed items; in this case, `indices` must be a `AbstractUnitRange`.
1780

1781
To insert `replacement` before an index `n` without removing any items, use
1782
`splice!(collection, n:n-1, replacement)`.
1783

1784
!!! compat "Julia 1.5"
1785
    Prior to Julia 1.5, `indices` must always be a `UnitRange`.
1786

1787
!!! compat "Julia 1.8"
1788
    Prior to Julia 1.8, `indices` must be a `UnitRange` if splicing in replacement values.
1789

1790
# Examples
1791
```jldoctest
1792
julia> A = [-1, -2, -3, 5, 4, 3, -1]; splice!(A, 4:3, 2)
1793
Int64[]
1794

1795
julia> A
1796
8-element Vector{Int64}:
1797
 -1
1798
 -2
1799
 -3
1800
  2
1801
  5
1802
  4
1803
  3
1804
 -1
1805
```
1806
"""
1807
function splice!(a::Vector, r::AbstractUnitRange{<:Integer}, ins=_default_splice)
105,766✔
1808
    v = a[r]
105,774✔
1809
    m = length(ins)
71,828✔
1810
    if m == 0
71,828✔
1811
        deleteat!(a, r)
74,249✔
1812
        return v
37,185✔
1813
    end
1814

1815
    n = length(a)
34,643✔
1816
    f = first(r)
34,643✔
1817
    l = last(r)
34,643✔
1818
    d = length(r)
34,643✔
1819

1820
    if m < d
34,643✔
1821
        delta = d - m
12,662✔
1822
        _deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
19,096✔
1823
    elseif m > d
21,981✔
1824
        _growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
21,847✔
1825
    end
1826

1827
    k = 1
34,560✔
1828
    for x in ins
46,149✔
1829
        a[f+k-1] = x
5,374,274✔
1830
        k += 1
4,030,195✔
1831
    end
5,396,522✔
1832
    return v
34,643✔
1833
end
1834

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

1837
function empty!(a::Vector)
94,237✔
1838
    _deleteend!(a, length(a))
75,797,736✔
1839
    return a
75,797,736✔
1840
end
1841

1842
# use memcmp for cmp on byte arrays
1843
function cmp(a::Array{UInt8,1}, b::Array{UInt8,1})
3✔
1844
    ta = @_gc_preserve_begin a
3✔
1845
    tb = @_gc_preserve_begin b
3✔
1846
    pa = unsafe_convert(Ptr{Cvoid}, a)
3✔
1847
    pb = unsafe_convert(Ptr{Cvoid}, b)
3✔
1848
    c = memcmp(pa, pb, min(length(a),length(b)))
3✔
1849
    @_gc_preserve_end ta
3✔
1850
    @_gc_preserve_end tb
3✔
1851
    return c < 0 ? -1 : c > 0 ? +1 : cmp(length(a),length(b))
3✔
1852
end
1853

1854
const BitIntegerArray{N} = Union{map(T->Array{T,N}, BitInteger_types)...} where N
×
1855
# use memcmp for == on bit integer types
1856
function ==(a::Arr, b::Arr) where {Arr <: BitIntegerArray}
1,669✔
1857
    if size(a) == size(b)
3,278✔
1858
        ta = @_gc_preserve_begin a
1,669✔
1859
        tb = @_gc_preserve_begin b
1,669✔
1860
        pa = unsafe_convert(Ptr{Cvoid}, a)
1,669✔
1861
        pb = unsafe_convert(Ptr{Cvoid}, b)
1,669✔
1862
        c = memcmp(pa, pb, sizeof(eltype(Arr)) * length(a))
1,669✔
1863
        @_gc_preserve_end ta
1,669✔
1864
        @_gc_preserve_end tb
1,669✔
1865
        return c == 0
1,669✔
1866
    else
1867
        return false
×
1868
    end
1869
end
1870

1871
function ==(a::Arr, b::Arr) where Arr <: BitIntegerArray{1}
8,459✔
1872
    len = length(a)
46,491✔
1873
    if len == length(b)
46,491✔
1874
        ta = @_gc_preserve_begin a
46,366✔
1875
        tb = @_gc_preserve_begin b
46,366✔
1876
        T = eltype(Arr)
1,260✔
1877
        pa = unsafe_convert(Ptr{T}, a)
46,366✔
1878
        pb = unsafe_convert(Ptr{T}, b)
46,366✔
1879
        c = memcmp(pa, pb, sizeof(T) * len)
46,366✔
1880
        @_gc_preserve_end ta
46,366✔
1881
        @_gc_preserve_end tb
46,366✔
1882
        return c == 0
46,366✔
1883
    else
1884
        return false
125✔
1885
    end
1886
end
1887

1888
"""
1889
    reverse(v [, start=firstindex(v) [, stop=lastindex(v) ]] )
1890

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

1894
# Examples
1895
```jldoctest
1896
julia> A = Vector(1:5)
1897
5-element Vector{Int64}:
1898
 1
1899
 2
1900
 3
1901
 4
1902
 5
1903

1904
julia> reverse(A)
1905
5-element Vector{Int64}:
1906
 5
1907
 4
1908
 3
1909
 2
1910
 1
1911

1912
julia> reverse(A, 1, 4)
1913
5-element Vector{Int64}:
1914
 4
1915
 3
1916
 2
1917
 1
1918
 5
1919

1920
julia> reverse(A, 3, 5)
1921
5-element Vector{Int64}:
1922
 1
1923
 2
1924
 5
1925
 4
1926
 3
1927
```
1928
"""
1929
function reverse(A::AbstractVector, start::Integer, stop::Integer=lastindex(A))
5,296✔
1930
    s, n = Int(start), Int(stop)
586✔
1931
    B = similar(A)
5,297✔
1932
    for i = firstindex(A):s-1
5,300✔
1933
        B[i] = A[i]
14✔
1934
    end
24✔
1935
    for i = s:n
10,584✔
1936
        B[i] = A[n+s-i]
245,668✔
1937
    end
486,044✔
1938
    for i = n+1:lastindex(A)
5,300✔
1939
        B[i] = A[i]
20✔
1940
    end
36✔
1941
    return B
5,296✔
1942
end
1943

1944
# 1d special cases of reverse(A; dims) and reverse!(A; dims):
1945
for (f,_f) in ((:reverse,:_reverse), (:reverse!,:_reverse!))
1946
    @eval begin
1947
        $f(A::AbstractVector; dims=:) = $_f(A, dims)
95,553,264✔
1948
        $_f(A::AbstractVector, ::Colon) = $f(A, firstindex(A), lastindex(A))
7,302✔
1949
        $_f(A::AbstractVector, dim::Tuple{Integer}) = $_f(A, first(dim))
×
1950
        function $_f(A::AbstractVector, dim::Integer)
7✔
1951
            dim == 1 || _throw_argerror(LazyString("invalid dimension ", dim, " ≠ 1"))
11✔
1952
            return $_f(A, :)
4✔
1953
        end
1954
    end
1955
end
1956

1957
function reverseind(a::AbstractVector, i::Integer)
3✔
1958
    li = LinearIndices(a)
3✔
1959
    first(li) + last(li) - i
3✔
1960
end
1961

1962
# This implementation of `midpoint` is performance-optimized but safe
1963
# only if `lo <= hi`.
1964
midpoint(lo::T, hi::T) where T<:Integer = lo + ((hi - lo) >>> 0x01)
15,627,659✔
1965
midpoint(lo::Integer, hi::Integer) = midpoint(promote(lo, hi)...)
×
1966

1967
"""
1968
    reverse!(v [, start=firstindex(v) [, stop=lastindex(v) ]]) -> v
1969

1970
In-place version of [`reverse`](@ref).
1971

1972
# Examples
1973
```jldoctest
1974
julia> A = Vector(1:5)
1975
5-element Vector{Int64}:
1976
 1
1977
 2
1978
 3
1979
 4
1980
 5
1981

1982
julia> reverse!(A);
1983

1984
julia> A
1985
5-element Vector{Int64}:
1986
 5
1987
 4
1988
 3
1989
 2
1990
 1
1991
```
1992
"""
1993
function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
66,197✔
1994
    s, n = Int(start), Int(stop)
9,201✔
1995
    if n > s # non-empty and non-trivial
66,194✔
1996
        liv = LinearIndices(v)
62,275✔
1997
        if !(first(liv) ≤ s ≤ last(liv))
62,275✔
1998
            throw(BoundsError(v, s))
3✔
1999
        elseif !(first(liv) ≤ n ≤ last(liv))
62,272✔
2000
            throw(BoundsError(v, n))
1✔
2001
        end
2002
        r = n
8,480✔
2003
        @inbounds for i in s:midpoint(s, n-1)
124,542✔
2004
            v[i], v[r] = v[r], v[i]
1,586,667✔
2005
            r -= 1
1,582,105✔
2006
        end
3,101,939✔
2007
    end
2008
    return v
66,190✔
2009
end
2010

2011
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
2012

2013
vcat() = Vector{Any}()
10,894✔
2014
hcat() = Vector{Any}()
1✔
2015

2016
function hcat(V::Vector{T}...) where T
556✔
2017
    height = length(V[1])
556✔
2018
    for j = 2:length(V)
557✔
2019
        if length(V[j]) != height
622✔
2020
            throw(DimensionMismatch("vectors must have same lengths"))
1✔
2021
        end
2022
    end
719✔
2023
    return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
555✔
2024
end
2025
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
6✔
2026

2027
function vcat(arrays::Vector{T}...) where T
39,691✔
2028
    n = 0
9,777✔
2029
    for a in arrays
39,691✔
2030
        n += length(a)
2,079,538✔
2031
    end
2,119,214✔
2032
    arr = Vector{T}(undef, n)
39,691✔
2033
    nd = 1
9,777✔
2034
    for a in arrays
39,691✔
2035
        na = length(a)
2,079,538✔
2036
        @assert nd + na <= 1 + length(arr) # Concurrent modification of arrays?
2,079,538✔
2037
        unsafe_copyto!(arr, nd, a, 1, na)
2,079,538✔
2038
        nd += na
2,079,538✔
2039
    end
2,119,214✔
2040
    return arr
39,691✔
2041
end
2042
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
33✔
2043

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

2046
## find ##
2047

2048
"""
2049
    findnext(A, i)
2050

2051
Find the next index after or including `i` of a `true` element of `A`,
2052
or `nothing` if not found.
2053

2054
Indices are of the same type as those returned by [`keys(A)`](@ref)
2055
and [`pairs(A)`](@ref).
2056

2057
# Examples
2058
```jldoctest
2059
julia> A = [false, false, true, false]
2060
4-element Vector{Bool}:
2061
 0
2062
 0
2063
 1
2064
 0
2065

2066
julia> findnext(A, 1)
2067
3
2068

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

2071
julia> A = [false false; true false]
2072
2×2 Matrix{Bool}:
2073
 0  0
2074
 1  0
2075

2076
julia> findnext(A, CartesianIndex(1, 1))
2077
CartesianIndex(2, 1)
2078
```
2079
"""
2080
findnext(A, start) = findnext(identity, A, start)
77,794✔
2081

2082
"""
2083
    findfirst(A)
2084

2085
Return the index or key of the first `true` value in `A`.
2086
Return `nothing` if no such value is found.
2087
To search for other kinds of values, pass a predicate as the first argument.
2088

2089
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2090
and [`pairs(A)`](@ref).
2091

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

2094
# Examples
2095
```jldoctest
2096
julia> A = [false, false, true, false]
2097
4-element Vector{Bool}:
2098
 0
2099
 0
2100
 1
2101
 0
2102

2103
julia> findfirst(A)
2104
3
2105

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

2108
julia> A = [false false; true false]
2109
2×2 Matrix{Bool}:
2110
 0  0
2111
 1  0
2112

2113
julia> findfirst(A)
2114
CartesianIndex(2, 1)
2115
```
2116
"""
2117
findfirst(A) = findfirst(identity, A)
2✔
2118

2119
# Needed for bootstrap, and allows defining only an optimized findnext method
2120
findfirst(A::AbstractArray) = findnext(A, first(keys(A)))
11,848✔
2121

2122
"""
2123
    findnext(predicate::Function, A, i)
2124

2125
Find the next index after or including `i` of an element of `A`
2126
for which `predicate` returns `true`, or `nothing` if not found.
2127

2128
Indices are of the same type as those returned by [`keys(A)`](@ref)
2129
and [`pairs(A)`](@ref).
2130

2131
# Examples
2132
```jldoctest
2133
julia> A = [1, 4, 2, 2];
2134

2135
julia> findnext(isodd, A, 1)
2136
1
2137

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

2140
julia> A = [1 4; 2 2];
2141

2142
julia> findnext(isodd, A, CartesianIndex(1, 1))
2143
CartesianIndex(1, 1)
2144
```
2145
"""
2146
function findnext(testf::Function, A, start)
46,493✔
2147
    i = oftype(first(keys(A)), start)
46,209✔
2148
    l = last(keys(A))
59,645,812✔
2149
    i > l && return nothing
59,645,812✔
2150
    while true
182,828,099✔
2151
        testf(A[i]) && return i
182,832,437✔
2152
        i == l && break
177,795,154✔
2153
        # nextind(A, l) can throw/overflow
2154
        i = nextind(A, i)
173,523,676✔
2155
    end
173,523,675✔
2156
    return nothing
4,271,477✔
2157
end
2158

2159
"""
2160
    findfirst(predicate::Function, A)
2161

2162
Return the index or key of the first element of `A` for which `predicate` returns `true`.
2163
Return `nothing` if there is no such element.
2164

2165
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2166
and [`pairs(A)`](@ref).
2167

2168
# Examples
2169
```jldoctest
2170
julia> A = [1, 4, 2, 2]
2171
4-element Vector{Int64}:
2172
 1
2173
 4
2174
 2
2175
 2
2176

2177
julia> findfirst(iseven, A)
2178
2
2179

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

2182
julia> findfirst(isequal(4), A)
2183
2
2184

2185
julia> A = [1 4; 2 2]
2186
2×2 Matrix{Int64}:
2187
 1  4
2188
 2  2
2189

2190
julia> findfirst(iseven, A)
2191
CartesianIndex(2, 1)
2192
```
2193
"""
2194
function findfirst(testf::Function, A)
14✔
2195
    for (i, a) in pairs(A)
22✔
2196
        testf(a) && return i
14✔
2197
    end
11✔
2198
    return nothing
7✔
2199
end
2200

2201
# Needed for bootstrap, and allows defining only an optimized findnext method
2202
findfirst(testf::Function, A::Union{AbstractArray, AbstractString}) =
242,680,841✔
2203
    findnext(testf, A, first(keys(A)))
2204

2205
findfirst(p::Union{Fix2{typeof(isequal),Int},Fix2{typeof(==),Int}}, r::OneTo{Int}) =
3✔
2206
    1 <= p.x <= r.stop ? p.x : nothing
2207

2208
findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::AbstractUnitRange) where {T<:Integer} =
4✔
2209
    first(r) <= p.x <= last(r) ? firstindex(r) + Int(p.x - first(r)) : nothing
2210

2211
function findfirst(p::Union{Fix2{typeof(isequal),T},Fix2{typeof(==),T}}, r::StepRange{T,S}) where {T,S}
6✔
2212
    isempty(r) && return nothing
6✔
2213
    minimum(r) <= p.x <= maximum(r) || return nothing
7✔
2214
    d = convert(S, p.x - first(r))::S
3✔
2215
    iszero(d % step(r)) || return nothing
3✔
2216
    return d ÷ step(r) + 1
3✔
2217
end
2218

2219
"""
2220
    findprev(A, i)
2221

2222
Find the previous index before or including `i` of a `true` element of `A`,
2223
or `nothing` if not found.
2224

2225
Indices are of the same type as those returned by [`keys(A)`](@ref)
2226
and [`pairs(A)`](@ref).
2227

2228
See also: [`findnext`](@ref), [`findfirst`](@ref), [`findall`](@ref).
2229

2230
# Examples
2231
```jldoctest
2232
julia> A = [false, false, true, true]
2233
4-element Vector{Bool}:
2234
 0
2235
 0
2236
 1
2237
 1
2238

2239
julia> findprev(A, 3)
2240
3
2241

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

2244
julia> A = [false false; true true]
2245
2×2 Matrix{Bool}:
2246
 0  0
2247
 1  1
2248

2249
julia> findprev(A, CartesianIndex(2, 1))
2250
CartesianIndex(2, 1)
2251
```
2252
"""
2253
findprev(A, start) = findprev(identity, A, start)
12,283✔
2254

2255
"""
2256
    findlast(A)
2257

2258
Return the index or key of the last `true` value in `A`.
2259
Return `nothing` if there is no `true` value in `A`.
2260

2261
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2262
and [`pairs(A)`](@ref).
2263

2264
See also: [`findfirst`](@ref), [`findprev`](@ref), [`findall`](@ref).
2265

2266
# Examples
2267
```jldoctest
2268
julia> A = [true, false, true, false]
2269
4-element Vector{Bool}:
2270
 1
2271
 0
2272
 1
2273
 0
2274

2275
julia> findlast(A)
2276
3
2277

2278
julia> A = falses(2,2);
2279

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

2282
julia> A = [true false; true false]
2283
2×2 Matrix{Bool}:
2284
 1  0
2285
 1  0
2286

2287
julia> findlast(A)
2288
CartesianIndex(2, 1)
2289
```
2290
"""
2291
findlast(A) = findlast(identity, A)
23✔
2292

2293
# Needed for bootstrap, and allows defining only an optimized findprev method
2294
findlast(A::AbstractArray) = findprev(A, last(keys(A)))
4,086✔
2295

2296
"""
2297
    findprev(predicate::Function, A, i)
2298

2299
Find the previous index before or including `i` of an element of `A`
2300
for which `predicate` returns `true`, or `nothing` if not found.
2301

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

2305
# Examples
2306
```jldoctest
2307
julia> A = [4, 6, 1, 2]
2308
4-element Vector{Int64}:
2309
 4
2310
 6
2311
 1
2312
 2
2313

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

2316
julia> findprev(isodd, A, 3)
2317
3
2318

2319
julia> A = [4 6; 1 2]
2320
2×2 Matrix{Int64}:
2321
 4  6
2322
 1  2
2323

2324
julia> findprev(isodd, A, CartesianIndex(1, 2))
2325
CartesianIndex(2, 1)
2326
```
2327
"""
2328
function findprev(testf::Function, A, start)
36,560✔
2329
    f = first(keys(A))
36,560✔
2330
    i = oftype(f, start)
36,565✔
2331
    i < f && return nothing
38,107✔
2332
    while true
185,229✔
2333
        testf(A[i]) && return i
185,271✔
2334
        i == f && break
147,174✔
2335
        # prevind(A, f) can throw/underflow
2336
        i = prevind(A, i)
147,125✔
2337
    end
147,123✔
2338
    return nothing
48✔
2339
end
2340

2341
"""
2342
    findlast(predicate::Function, A)
2343

2344
Return the index or key of the last element of `A` for which `predicate` returns `true`.
2345
Return `nothing` if there is no such element.
2346

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

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

2359
julia> findlast(isodd, A)
2360
3
2361

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

2364
julia> A = [1 2; 3 4]
2365
2×2 Matrix{Int64}:
2366
 1  2
2367
 3  4
2368

2369
julia> findlast(isodd, A)
2370
CartesianIndex(2, 1)
2371
```
2372
"""
2373
function findlast(testf::Function, A)
4✔
2374
    for (i, a) in Iterators.reverse(pairs(A))
4✔
2375
        testf(a) && return i
6✔
2376
    end
6✔
2377
    return nothing
2✔
2378
end
2379

2380
# Needed for bootstrap, and allows defining only an optimized findprev method
2381
findlast(testf::Function, A::Union{AbstractArray, AbstractString}) =
13,137✔
2382
    findprev(testf, A, last(keys(A)))
2383

2384
"""
2385
    findall(f::Function, A)
2386

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

2390
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2391
and [`pairs(A)`](@ref).
2392

2393
# Examples
2394
```jldoctest
2395
julia> x = [1, 3, 4]
2396
3-element Vector{Int64}:
2397
 1
2398
 3
2399
 4
2400

2401
julia> findall(isodd, x)
2402
2-element Vector{Int64}:
2403
 1
2404
 2
2405

2406
julia> A = [1 2 0; 3 4 0]
2407
2×3 Matrix{Int64}:
2408
 1  2  0
2409
 3  4  0
2410
julia> findall(isodd, A)
2411
2-element Vector{CartesianIndex{2}}:
2412
 CartesianIndex(1, 1)
2413
 CartesianIndex(2, 1)
2414

2415
julia> findall(!iszero, A)
2416
4-element Vector{CartesianIndex{2}}:
2417
 CartesianIndex(1, 1)
2418
 CartesianIndex(2, 1)
2419
 CartesianIndex(1, 2)
2420
 CartesianIndex(2, 2)
2421

2422
julia> d = Dict(:A => 10, :B => -1, :C => 0)
2423
Dict{Symbol, Int64} with 3 entries:
2424
  :A => 10
2425
  :B => -1
2426
  :C => 0
2427

2428
julia> findall(x -> x >= 0, d)
2429
2-element Vector{Symbol}:
2430
 :A
2431
 :C
2432

2433
```
2434
"""
2435
function findall(testf::Function, A)
55✔
2436
    gen = (first(p) for p in pairs(A) if testf(last(p)))
55✔
2437
    @default_eltype(gen) === Union{} ? collect(@default_eltype(keys(A)), gen) : collect(gen)
×
2438
end
2439

2440
# Broadcasting is much faster for small testf, and computing
2441
# integer indices from logical index using findall has a negligible cost
2442
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))
323✔
2443

2444
"""
2445
    findall(A)
2446

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

2451
Indices or keys are of the same type as those returned by [`keys(A)`](@ref)
2452
and [`pairs(A)`](@ref).
2453

2454
See also: [`findfirst`](@ref), [`searchsorted`](@ref).
2455

2456
# Examples
2457
```jldoctest
2458
julia> A = [true, false, false, true]
2459
4-element Vector{Bool}:
2460
 1
2461
 0
2462
 0
2463
 1
2464

2465
julia> findall(A)
2466
2-element Vector{Int64}:
2467
 1
2468
 4
2469

2470
julia> A = [true false; false true]
2471
2×2 Matrix{Bool}:
2472
 1  0
2473
 0  1
2474

2475
julia> findall(A)
2476
2-element Vector{CartesianIndex{2}}:
2477
 CartesianIndex(1, 1)
2478
 CartesianIndex(2, 2)
2479

2480
julia> findall(falses(3))
2481
Int64[]
2482
```
2483
"""
2484
function findall(A)
3✔
2485
    collect(first(p) for p in pairs(A) if last(p))
3✔
2486
end
2487

2488
# Allocating result upfront is faster (possible only when collection can be iterated twice)
2489
function findall(A::AbstractArray{Bool})
2,828✔
2490
    n = count(A)
2,833✔
2491
    I = Vector{eltype(keys(A))}(undef, n)
2,828✔
2492
    cnt = 1
2,828✔
2493
    for (i,a) in pairs(A)
5,648✔
2494
        if a
125,635✔
2495
            I[cnt] = i
62,648✔
2496
            cnt += 1
62,648✔
2497
        end
2498
    end
248,447✔
2499
    I
2,828✔
2500
end
2501

2502
findall(x::Bool) = x ? [1] : Vector{Int}()
2✔
2503
findall(testf::Function, x::Number) = testf(x) ? [1] : Vector{Int}()
2✔
2504
findall(p::Fix2{typeof(in)}, x::Number) = x in p.x ? [1] : Vector{Int}()
2✔
2505

2506
# similar to Matlab's ismember
2507
"""
2508
    indexin(a, b)
2509

2510
Return an array containing the first index in `b` for
2511
each value in `a` that is a member of `b`. The output
2512
array contains `nothing` wherever `a` is not a member of `b`.
2513

2514
See also: [`sortperm`](@ref), [`findfirst`](@ref).
2515

2516
# Examples
2517
```jldoctest
2518
julia> a = ['a', 'b', 'c', 'b', 'd', 'a'];
2519

2520
julia> b = ['a', 'b', 'c'];
2521

2522
julia> indexin(a, b)
2523
6-element Vector{Union{Nothing, Int64}}:
2524
 1
2525
 2
2526
 3
2527
 2
2528
  nothing
2529
 1
2530

2531
julia> indexin(b, a)
2532
3-element Vector{Union{Nothing, Int64}}:
2533
 1
2534
 2
2535
 3
2536
```
2537
"""
2538
function indexin(a, b::AbstractArray)
7✔
2539
    inds = keys(b)
7✔
2540
    bdict = Dict{eltype(b),eltype(inds)}()
7✔
2541
    for (val, ind) in zip(b, inds)
14✔
2542
        get!(bdict, val, ind)
30✔
2543
    end
53✔
2544
    return Union{eltype(inds), Nothing}[
7✔
2545
        get(bdict, i, nothing) for i in a
2546
    ]
2547
end
2548

2549
function _findin(a::Union{AbstractArray, Tuple}, b)
13✔
2550
    ind  = Vector{eltype(keys(a))}()
13✔
2551
    bset = Set(b)
13✔
2552
    @inbounds for (i,ai) in pairs(a)
25✔
2553
        ai in bset && push!(ind, i)
53✔
2554
    end
94✔
2555
    ind
13✔
2556
end
2557

2558
# If two collections are already sorted, _findin can be computed with
2559
# a single traversal of the two collections. This is much faster than
2560
# using a hash table (although it has the same complexity).
2561
function _sortedfindin(v::Union{AbstractArray, Tuple}, w)
9✔
2562
    viter, witer = keys(v), eachindex(w)
9✔
2563
    out  = eltype(viter)[]
9✔
2564
    vy, wy = iterate(viter), iterate(witer)
17✔
2565
    if vy === nothing || wy === nothing
17✔
2566
        return out
2✔
2567
    end
2568
    viteri, i = vy
7✔
2569
    witerj, j = wy
7✔
2570
    @inbounds begin
7✔
2571
        vi, wj = v[viteri], w[witerj]
7✔
2572
        while true
54✔
2573
            if isless(vi, wj)
56✔
2574
                vy = iterate(viter, i)
25✔
2575
                if vy === nothing
14✔
2576
                    break
2✔
2577
                end
2578
                viteri, i = vy
12✔
2579
                vi        = v[viteri]
12✔
2580
            elseif isless(wj, vi)
40✔
2581
                wy = iterate(witer, j)
44✔
2582
                if wy === nothing
24✔
2583
                    break
4✔
2584
                end
2585
                witerj, j = wy
20✔
2586
                wj        = w[witerj]
20✔
2587
            else
2588
                push!(out, viteri)
16✔
2589
                vy = iterate(viter, i)
25✔
2590
                if vy === nothing
16✔
2591
                    break
1✔
2592
                end
2593
                # We only increment the v iterator because v can have
2594
                # repeated matches to a single value in w
2595
                viteri, i = vy
15✔
2596
                vi        = v[viteri]
15✔
2597
            end
2598
        end
47✔
2599
    end
2600
    return out
7✔
2601
end
2602

2603
function findall(pred::Fix2{typeof(in),<:Union{Array{<:Real},Real}}, x::Array{<:Real})
15✔
2604
    if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
25✔
2605
        return _sortedfindin(x, pred.x)
9✔
2606
    else
2607
        return _findin(x, pred.x)
6✔
2608
    end
2609
end
2610
# issorted fails for some element types so the method above has to be restricted
2611
# to element with isless/< defined.
2612
findall(pred::Fix2{typeof(in)}, x::AbstractArray) = _findin(x, pred.x)
11✔
2613
findall(pred::Fix2{typeof(in)}, x::Tuple) = _findin(x, pred.x)
×
2614

2615
# Copying subregions
2616
function indcopy(sz::Dims, I::Vector)
1✔
2617
    n = length(I)
1✔
2618
    s = sz[n]
1✔
2619
    for i = n+1:length(sz)
1✔
2620
        s *= sz[i]
×
2621
    end
×
2622
    dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
2✔
2623
    src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
2✔
2624
    dst, src
1✔
2625
end
2626

2627
function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
1✔
2628
    n = length(I)
1✔
2629
    s = sz[n]
1✔
2630
    for i = n+1:length(sz)
1✔
2631
        s *= sz[i]
×
2632
    end
×
2633
    dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
3✔
2634
    src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
3✔
2635
    dst, src
1✔
2636
end
2637

2638
## Filter ##
2639

2640
"""
2641
    filter(f, a)
2642

2643
Return a copy of collection `a`, removing elements for which `f` is `false`.
2644
The function `f` is passed one argument.
2645

2646
!!! compat "Julia 1.4"
2647
    Support for `a` as a tuple requires at least Julia 1.4.
2648

2649
See also: [`filter!`](@ref), [`Iterators.filter`](@ref).
2650

2651
# Examples
2652
```jldoctest
2653
julia> a = 1:10
2654
1:10
2655

2656
julia> filter(isodd, a)
2657
5-element Vector{Int64}:
2658
 1
2659
 3
2660
 5
2661
 7
2662
 9
2663
```
2664
"""
2665
function filter(f, a::Array{T, N}) where {T, N}
19,756✔
2666
    j = 1
2,448✔
2667
    b = Vector{T}(undef, length(a))
19,756✔
2668
    for ai in a
20,006✔
2669
        @inbounds b[j] = ai
769,900✔
2670
        j = ifelse(f(ai)::Bool, j+1, j)
772,145✔
2671
    end
789,343✔
2672
    resize!(b, j-1)
39,512✔
2673
    sizehint!(b, length(b))
19,756✔
2674
    b
19,756✔
2675
end
2676

2677
function filter(f, a::AbstractArray)
375✔
2678
    (IndexStyle(a) != IndexLinear()) && return a[map(f, a)::AbstractArray{Bool}]
375✔
2679

2680
    j = 1
375✔
2681
    idxs = Vector{Int}(undef, length(a))
378✔
2682
    for idx in eachindex(a)
621✔
2683
        @inbounds idxs[j] = idx
103,107✔
2684
        ai = @inbounds a[idx]
103,107✔
2685
        j = ifelse(f(ai)::Bool, j+1, j)
137,175✔
2686
    end
205,967✔
2687
    resize!(idxs, j-1)
748✔
2688
    res = a[idxs]
374✔
2689
    empty!(idxs)
374✔
2690
    sizehint!(idxs, 0)
374✔
2691
    return res
374✔
2692
end
2693

2694
"""
2695
    filter!(f, a)
2696

2697
Update collection `a`, removing elements for which `f` is `false`.
2698
The function `f` is passed one argument.
2699

2700
# Examples
2701
```jldoctest
2702
julia> filter!(isodd, Vector(1:10))
2703
5-element Vector{Int64}:
2704
 1
2705
 3
2706
 5
2707
 7
2708
 9
2709
```
2710
"""
2711
function filter!(f, a::AbstractVector)
54,046,267✔
2712
    j = firstindex(a)
441,580✔
2713
    for ai in a
59,567,246✔
2714
        @inbounds a[j] = ai
62,179,523✔
2715
        j = ifelse(f(ai)::Bool, nextind(a, j), j)
64,802,968✔
2716
    end
110,704,821✔
2717
    j > lastindex(a) && return a
54,046,267✔
2718
    if a isa Vector
441,097✔
2719
        resize!(a, j-1)
955,432✔
2720
        sizehint!(a, j-1)
477,716✔
2721
    else
2722
        deleteat!(a, j:lastindex(a))
1✔
2723
    end
2724
    return a
477,717✔
2725
end
2726

2727
"""
2728
    filter(f)
2729

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

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

2736
# Examples
2737
```jldoctest
2738
julia> (1, 2, Inf, 4, NaN, 6) |> filter(isfinite)
2739
(1, 2, 4, 6)
2740

2741
julia> map(filter(iseven), [1:3, 2:4, 3:5])
2742
3-element Vector{Vector{Int64}}:
2743
 [2]
2744
 [2, 4]
2745
 [4]
2746
```
2747
!!! compat "Julia 1.9"
2748
    This method requires at least Julia 1.9.
2749
"""
2750
function filter(f)
1✔
2751
    Fix1(filter, f)
1✔
2752
end
2753

2754
"""
2755
    keepat!(a::Vector, inds)
2756
    keepat!(a::BitVector, inds)
2757

2758
Remove the items at all the indices which are not given by `inds`,
2759
and return the modified `a`.
2760
Items which are kept are shifted to fill the resulting gaps.
2761

2762
`inds` must be an iterator of sorted and unique integer indices.
2763
See also [`deleteat!`](@ref).
2764

2765
!!! compat "Julia 1.7"
2766
    This function is available as of Julia 1.7.
2767

2768
# Examples
2769
```jldoctest
2770
julia> keepat!([6, 5, 4, 3, 2, 1], 1:2:5)
2771
3-element Vector{Int64}:
2772
 6
2773
 4
2774
 2
2775
```
2776
"""
2777
keepat!(a::Vector, inds) = _keepat!(a, inds)
9✔
2778

2779
"""
2780
    keepat!(a::Vector, m::AbstractVector{Bool})
2781
    keepat!(a::BitVector, m::AbstractVector{Bool})
2782

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

2787
# Examples
2788
```jldoctest
2789
julia> a = [:a, :b, :c];
2790

2791
julia> keepat!(a, [true, false, true])
2792
2-element Vector{Symbol}:
2793
 :a
2794
 :c
2795

2796
julia> a
2797
2-element Vector{Symbol}:
2798
 :a
2799
 :c
2800
```
2801
"""
2802
keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m)
4✔
2803

2804
# set-like operators for vectors
2805
# These are moderately efficient, preserve order, and remove dupes.
2806

2807
_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x)
15,918✔
2808
    # P, U force specialization
2809
    if pred(x, state)
15,010✔
2810
        update!(state, x)
7,151✔
2811
        true
7,151✔
2812
    else
2813
        false
7,859✔
2814
    end
2815
end
2816

2817
_grow_filter!(seen) = _unique_filter!(∉, push!, seen)
159✔
2818
_shrink_filter!(keep) = _unique_filter!(∈, pop!, keep)
992✔
2819

2820
function _grow!(pred!, v::AbstractVector, itrs)
167✔
2821
    filter!(pred!, v) # uniquify v
169✔
2822
    for itr in itrs
169✔
2823
        mapfilter(pred!, push!, itr, v)
341✔
2824
    end
504✔
2825
    return v
169✔
2826
end
2827

2828
union!(v::AbstractVector{T}, itrs...) where {T} =
159✔
2829
    _grow!(_grow_filter!(sizehint!(Set{T}(), length(v))), v, itrs)
2830

2831
symdiff!(v::AbstractVector{T}, itrs...) where {T} =
10✔
2832
    _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs)
2833

2834
function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F
×
2835
    seen = Set{eltype(v)}()
×
2836
    filter!(_grow_filter!(seen), v)
×
2837
    shrinker!(seen, itrs...)
×
2838
    filter!(in(seen), v)
×
2839
end
2840

2841
intersect!(v::AbstractVector, itrs...) = _shrink!(intersect!, v, itrs)
×
2842
setdiff!(  v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs)
×
2843

2844
vectorfilter(T::Type, f, v) = T[x for x in v if f(x)]
983✔
2845

2846
function _shrink(shrinker!::F, itr, itrs) where F
928✔
2847
    T = promote_eltype(itr, itrs...)
848✔
2848
    keep = shrinker!(Set{T}(itr), itrs...)
1,935✔
2849
    vectorfilter(T, _shrink_filter!(keep), itr)
928✔
2850
end
2851

2852
intersect(itr, itrs...) = _shrink(intersect!, itr, itrs)
401✔
2853
setdiff(  itr, itrs...) = _shrink(setdiff!, itr, itrs)
527✔
2854

2855
function intersect(v::AbstractVector, r::AbstractRange)
54✔
2856
    T = promote_eltype(v, r)
6✔
2857
    common = Iterators.filter(in(r), v)
54✔
2858
    seen = Set{T}(common)
54✔
2859
    return vectorfilter(T, _shrink_filter!(seen), common)
54✔
2860
end
2861
intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
2✔
2862

2863
# Here instead of range.jl for bootstrapping because `@propagate_inbounds` depends on Vectors.
2864
@propagate_inbounds function getindex(v::AbstractRange, i::Integer)
27,425,068✔
2865
    if i isa Bool # Not via dispatch to avoid ambiguities
27,424,701✔
2866
        throw(ArgumentError("invalid index: $i of type Bool"))
6✔
2867
    else
2868
        _getindex(v, i)
642,940,595✔
2869
    end
2870
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

© 2025 Coveralls, Inc