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

JuliaLang / julia / #38182

15 Aug 2025 03:55AM UTC coverage: 77.87% (-0.4%) from 78.28%
#38182

push

local

web-flow
🤖 [master] Bump the SparseArrays stdlib from 30201ab to bb5ecc0 (#59263)

Stdlib: SparseArrays
URL: https://github.com/JuliaSparse/SparseArrays.jl.git
Stdlib branch: main
Julia branch: master
Old commit: 30201ab
New commit: bb5ecc0
Julia version: 1.13.0-DEV
SparseArrays version: 1.13.0
Bump invoked by: @ViralBShah
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
https://github.com/JuliaSparse/SparseArrays.jl/compare/30201abcb...bb5ecc091

```
$ git log --oneline 30201ab..bb5ecc0
bb5ecc0 fast quadratic form for dense matrix, sparse vectors (#640)
34ece87 Extend 3-arg `dot` to generic `HermOrSym` sparse matrices (#643)
095b685 Exclude unintended complex symmetric sparse matrices from 3-arg `dot` (#642)
8049287 Fix signature for 2-arg matrix-matrix `dot` (#641)
cff971d Make cond(::SparseMatrix, 1 / Inf) discoverable from 2-norm error (#629)
```

Co-authored-by: ViralBShah <744411+ViralBShah@users.noreply.github.com>

48274 of 61993 relevant lines covered (77.87%)

9571166.83 hits per line

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

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

3
## types ##
4

5
"""
6
    <:(T1, T2)::Bool
7

8
Subtyping relation, defined between two types. In Julia, a type `S` is said to be a
9
*subtype* of a type `T` if and only if we have `S <: T`.
10

11
For any type `L` and any type `R`, `L <: R` implies that any value `v` of type `L`
12
is also of type `R`. I.e., `(L <: R) && (v isa L)` implies `v isa R`.
13

14
The subtyping relation is a *partial order*. I.e., `<:` is:
15

16
* *reflexive*: for any type `T`, `T <: T` holds
17

18
* *antisymmetric*: for any type `A` and any type `B`, `(A <: B) && (B <: A)`
19
  implies `A == B`
20

21
* *transitive*: for any type `A`, any type `B` and any type `C`;
22
  `(A <: B) && (B <: C)` implies `A <: C`
23

24
See also info on [Types](@ref man-types), [`Union{}`](@ref), [`Any`](@ref), [`isa`](@ref).
25

26
# Examples
27
```jldoctest
28
julia> Float64 <: AbstractFloat
29
true
30

31
julia> Vector{Int} <: AbstractArray
32
true
33

34
julia> Matrix{Float64} <: Matrix{AbstractFloat}  # `Matrix` is invariant
35
false
36

37
julia> Tuple{Float64} <: Tuple{AbstractFloat}    # `Tuple` is covariant
38
true
39

40
julia> Union{} <: Int  # The bottom type, `Union{}`, subtypes each type.
41
true
42

43
julia> Union{} <: Float32 <: AbstractFloat <: Real <: Number <: Any  # Operator chaining
44
true
45
```
46

47
The `<:` keyword also has several syntactic uses which represent the same subtyping relation,
48
but which do not execute the operator or return a Bool:
49

50
* To specify the lower bound and the upper bound on a parameter of a
51
  [`UnionAll`](@ref) type in a [`where`](@ref) statement.
52

53
* To specify the lower bound and the upper bound on a (static) parameter of a
54
  method, see [Parametric Methods](@ref).
55

56
* To define a subtyping relation while declaring a new type, see [`struct`](@ref)
57
  and [`abstract type`](@ref).
58
"""
59
(<:)
60

61
import Core: >:
62

63
"""
64
    >:(T1, T2)
65

66
Supertype operator, equivalent to `T2 <: T1`.
67
"""
68
>:
69

70
"""
71
    supertype(T::Union{DataType, UnionAll})
72

73
Return the direct supertype of type `T`.
74
`T` can be a [`DataType`](@ref) or a [`UnionAll`](@ref) type. Does not support
75
type [`Union`](@ref)s. Also see info on [Types](@ref man-types).
76

77
# Examples
78
```jldoctest
79
julia> supertype(Int32)
80
Signed
81

82
julia> supertype(Vector)
83
DenseVector (alias for DenseArray{T, 1} where T)
84
```
85
"""
86
supertype(T::DataType) = (@_total_meta; T.super)
157,000✔
87
supertype(T::UnionAll) = (@_total_meta; UnionAll(T.var, supertype(T.body)))
6✔
88

89
## generic comparison ##
90

91
"""
92
    ==(x, y)
93

94
Generic equality operator. Falls back to [`===`](@ref).
95
Should be implemented for all types with a notion of equality, based on the abstract value
96
that an instance represents. For example, all numeric types are compared by numeric value,
97
ignoring type. Strings are compared as sequences of characters, ignoring encoding.
98
Collections of the same type generally compare their key sets, and if those are `==`, then compare the values
99
for each of those keys, returning true if all such pairs are `==`.
100
Other properties are typically not taken into account (such as the exact type).
101

102
This operator follows IEEE semantics for floating-point numbers: `0.0 == -0.0` and
103
`NaN != NaN`.
104

105
The result is of type `Bool`, except when one of the operands is [`missing`](@ref),
106
in which case `missing` is returned
107
([three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic)).
108
Collections generally implement three-valued logic akin to [`all`](@ref), returning
109
missing if any operands contain missing values and all other pairs are equal.
110
Use [`isequal`](@ref) or [`===`](@ref) to always get a `Bool` result.
111

112
# Implementation
113
New numeric types should implement this function for two arguments of the new type, and
114
handle comparison to other types via promotion rules where possible.
115

116
Equality and hashing are intimately related; two values that are considered [`isequal`](@ref) **must**
117
have the same [`hash`](@ref) and by default `isequal` falls back to `==`. If a type customizes the behavior of `==` and/or [`isequal`](@ref),
118
then [`hash`](@ref) must be similarly implemented to ensure `isequal` and `hash` agree. `Set`s, `Dict`s, and many other internal
119
implementations assume that this invariant holds.
120

121
If some type defines `==`, [`isequal`](@ref), and [`isless`](@ref) then it should
122
also implement [`<`](@ref) to ensure consistency of comparisons.
123
"""
124
==
125

126
"""
127
    isequal(x, y)::Bool
128

129
Similar to [`==`](@ref), except for the treatment of floating point numbers
130
and of missing values. `isequal` treats all floating-point `NaN` values as equal
131
to each other, treats `-0.0` as unequal to `0.0`, and [`missing`](@ref) as equal
132
to `missing`. Always returns a `Bool` value.
133

134
`isequal` is an equivalence relation - it is reflexive (`===` implies `isequal`), symmetric
135
(`isequal(a, b)` implies `isequal(b, a)`) and transitive (`isequal(a, b)` and
136
`isequal(b, c)` implies `isequal(a, c)`).
137

138
# Implementation
139
The default implementation of `isequal` calls `==`, so a type that does not involve
140
floating-point values generally only needs to define `==`.
141

142
`isequal` is the comparison function used by hash tables (`Dict`). `isequal(x,y)` must imply
143
that `hash(x) == hash(y)`.
144

145
This typically means that types for which a custom `==` or `isequal` method exists must
146
implement a corresponding [`hash`](@ref) method (and vice versa). Collections typically
147
implement `isequal` by calling `isequal` recursively on all contents.
148

149
Furthermore, `isequal` is linked with [`isless`](@ref), and they work together to
150
define a fixed total ordering, where exactly one of `isequal(x, y)`, `isless(x, y)`, or
151
`isless(y, x)` must be `true` (and the other two `false`).
152

153
Scalar types generally do not need to implement `isequal` separate from `==`, unless they
154
represent floating-point numbers amenable to a more efficient implementation than that
155
provided as a generic fallback (based on `isnan`, `signbit`, and `==`).
156

157
# Examples
158
```jldoctest
159
julia> isequal([1., NaN], [1., NaN])
160
true
161

162
julia> [1., NaN] == [1., NaN]
163
false
164

165
julia> 0.0 == -0.0
166
true
167

168
julia> isequal(0.0, -0.0)
169
false
170

171
julia> missing == missing
172
missing
173

174
julia> isequal(missing, missing)
175
true
176
```
177
"""
178
isequal(x, y) = (x == y)::Bool # all `missing` cases are handled in missing.jl
103,071,941✔
179

180
signequal(x, y) = signbit(x)::Bool == signbit(y)::Bool
334,544✔
181
signless(x, y) = signbit(x)::Bool & !signbit(y)::Bool
68,545✔
182

183
isequal(x::AbstractFloat, y::AbstractFloat) = (isnan(x) & isnan(y)) | signequal(x, y) & (x == y)::Bool
243,229✔
184
isequal(x::Real,          y::AbstractFloat) = (isnan(x) & isnan(y)) | signequal(x, y) & (x == y)::Bool
89,334✔
185
isequal(x::AbstractFloat, y::Real         ) = (isnan(x) & isnan(y)) | signequal(x, y) & (x == y)::Bool
1,997✔
186

187
"""
188
    isless(x, y)
189

190
Test whether `x` is less than `y`, according to a fixed total order (defined together with
191
[`isequal`](@ref)). `isless` is not defined for pairs `(x, y)` of all types. However, if it
192
is defined, it is expected to satisfy the following:
193
- If `isless(x, y)` is defined, then so is `isless(y, x)` and `isequal(x, y)`,
194
  and exactly one of those three yields `true`.
195
- The relation defined by `isless` is transitive, i.e.,
196
  `isless(x, y) && isless(y, z)` implies `isless(x, z)`.
197

198
Values that are normally unordered, such as `NaN`,
199
are ordered after regular values.
200
[`missing`](@ref) values are ordered last.
201

202
This is the default comparison used by [`sort!`](@ref).
203

204
# Implementation
205
Non-numeric types with a total order should implement this function.
206
Numeric types only need to implement it if they have special values such as `NaN`.
207
Types with a partial order should implement [`<`](@ref).
208
See the documentation on [Alternate Orderings](@ref) for how to define alternate
209
ordering methods that can be used in sorting and related functions.
210

211
# Examples
212
```jldoctest
213
julia> isless(1, 3)
214
true
215

216
julia> isless("Red", "Blue")
217
false
218
```
219
"""
220
function isless end
221

222
isless(x::AbstractFloat, y::AbstractFloat) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)
36,463✔
223
isless(x::Real,          y::AbstractFloat) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)
21,617✔
224
isless(x::AbstractFloat, y::Real         ) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)
11,721✔
225

226
# Performance optimization to reduce branching
227
# This is useful for sorting tuples of integers
228
# TODO: remove this when the compiler can optimize the generic version better
229
# See #48724 and #48753
230
isless(a::Tuple{BitInteger, BitInteger}, b::Tuple{BitInteger, BitInteger}) =
372✔
231
    isless(a[1], b[1]) | (isequal(a[1], b[1]) & isless(a[2], b[2]))
232

233
"""
234
    isgreater(x, y)
235

236
Not the inverse of `isless`! Test whether `x` is greater than `y`, according to
237
a fixed total order compatible with `min`.
238

239
Defined with `isless`, this function is usually `isless(y, x)`, but `NaN` and
240
[`missing`](@ref) are ordered as smaller than any regular value with `missing`
241
smaller than `NaN`.
242

243
So `isless` defines an ascending total order with `NaN` and `missing` as the
244
largest values and `isgreater` defines a descending total order with `NaN` and
245
`missing` as the smallest values.
246

247
!!! note
248

249
    Like `min`, `isgreater` orders containers (tuples, vectors, etc)
250
    lexicographically with `isless(y, x)` rather than recursively with itself:
251

252
    ```jldoctest
253
    julia> Base.isgreater(1, NaN) # 1 is greater than NaN
254
    true
255

256
    julia> Base.isgreater((1,), (NaN,)) # But (1,) is not greater than (NaN,)
257
    false
258

259
    julia> sort([1, 2, 3, NaN]; lt=Base.isgreater)
260
    4-element Vector{Float64}:
261
       3.0
262
       2.0
263
       1.0
264
     NaN
265

266
    julia> sort(tuple.([1, 2, 3, NaN]); lt=Base.isgreater)
267
    4-element Vector{Tuple{Float64}}:
268
     (NaN,)
269
     (3.0,)
270
     (2.0,)
271
     (1.0,)
272
    ```
273

274
# Implementation
275
This is unexported. Types should not usually implement this function. Instead, implement `isless`.
276
"""
277
isgreater(x, y) = isunordered(x) || isunordered(y) ? isless(x, y) : isless(y, x)
45,300✔
278

279
"""
280
    isunordered(x)
281

282
Return `true` if `x` is a value that is not orderable according to [`<`](@ref), such as `NaN`
283
or `missing`.
284

285
The values that evaluate to `true` with this predicate may be orderable with respect to other
286
orderings such as [`isless`](@ref).
287

288
!!! compat "Julia 1.7"
289
    This function requires Julia 1.7 or later.
290
"""
291
isunordered(x) = false
×
292
isunordered(x::AbstractFloat) = isnan(x)
81,119✔
293
isunordered(x::Missing) = true
×
294

295
==(T::Type, S::Type) = (@_total_meta; ccall(:jl_types_equal, Cint, (Any, Any), T, S) != 0)
12,796,312✔
296
!=(T::Type, S::Type) = (@_total_meta; !(T == S))
689,739✔
297
==(T::TypeVar, S::Type) = false
×
298
==(T::Type, S::TypeVar) = false
×
299

300
## comparison fallbacks ##
301

302
"""
303
    !=(x, y)
304
    ≠(x,y)
305

306
Not-equals comparison operator. Always gives the opposite answer as [`==`](@ref).
307

308
# Implementation
309
New types should generally not implement this, and rely on the fallback definition
310
`!=(x,y) = !(x==y)` instead.
311

312
# Examples
313
```jldoctest
314
julia> 3 != 2
315
true
316

317
julia> "foo" ≠ "foo"
318
false
319
```
320
"""
321
!=(x, y) = !(x == y)
2,147,483,647✔
322
const ≠ = !=
323

324
"""
325
    ===(x,y)::Bool
326
    ≡(x,y)::Bool
327

328
Determine whether `x` and `y` are identical, in the sense that no program could distinguish
329
them. First the types of `x` and `y` are compared. If those are identical, mutable objects
330
are compared by address in memory and immutable objects (such as numbers) are compared by
331
contents at the bit level. This function is sometimes called "egal".
332
It always returns a `Bool` value.
333

334
# Examples
335
```jldoctest
336
julia> a = [1, 2]; b = [1, 2];
337

338
julia> a == b
339
true
340

341
julia> a === b
342
false
343

344
julia> a === a
345
true
346
```
347
"""
348
===
349
const ≡ = ===
350

351
import Core: !==
352
"""
353
    !==(x, y)
354
    ≢(x,y)
355

356
Always gives the opposite answer as [`===`](@ref).
357

358
# Examples
359
```jldoctest
360
julia> a = [1, 2]; b = [1, 2];
361

362
julia> a ≢ b
363
true
364

365
julia> a ≢ a
366
false
367
```
368
"""
369
!==
370

371
const ≢ = !==
372

373
"""
374
    <(x, y)
375

376
Less-than comparison operator. Falls back to [`isless`](@ref).
377
Because of the behavior of floating-point NaN values, this operator implements
378
a partial order.
379

380
# Implementation
381
New types with a canonical partial order should implement this function for
382
two arguments of the new type.
383
Types with a canonical total order should implement [`isless`](@ref) instead.
384

385
See also [`isunordered`](@ref).
386

387
# Examples
388
```jldoctest
389
julia> 'a' < 'b'
390
true
391

392
julia> "abc" < "abd"
393
true
394

395
julia> 5 < 3
396
false
397
```
398
"""
399
<(x, y) = isless(x, y)
1,712,044,592✔
400

401
"""
402
    >(x, y)
403

404
Greater-than comparison operator. Falls back to `y < x`.
405

406
# Implementation
407
Generally, new types should implement [`<`](@ref) instead of this function,
408
and rely on the fallback definition `>(x, y) = y < x`.
409

410
# Examples
411
```jldoctest
412
julia> 'a' > 'b'
413
false
414

415
julia> 7 > 3 > 1
416
true
417

418
julia> "abc" > "abd"
419
false
420

421
julia> 5 > 3
422
true
423
```
424
"""
425
>(x, y) = y < x
2,147,483,647✔
426

427
"""
428
    <=(x, y)
429
    ≤(x,y)
430

431
Less-than-or-equals comparison operator. Falls back to `(x < y) | (x == y)`.
432

433
# Examples
434
```jldoctest
435
julia> 'a' <= 'b'
436
true
437

438
julia> 7 ≤ 7 ≤ 9
439
true
440

441
julia> "abc" ≤ "abc"
442
true
443

444
julia> 5 <= 3
445
false
446
```
447
"""
448
<=(x, y) = (x < y) | (x == y)
1,544,252,452✔
449
const ≤ = <=
450

451
"""
452
    >=(x, y)
453
    ≥(x,y)
454

455
Greater-than-or-equals comparison operator. Falls back to `y <= x`.
456

457
# Examples
458
```jldoctest
459
julia> 'a' >= 'b'
460
false
461

462
julia> 7 ≥ 7 ≥ 3
463
true
464

465
julia> "abc" ≥ "abc"
466
true
467

468
julia> 5 >= 3
469
true
470
```
471
"""
472
>=(x, y) = (y <= x)
2,147,483,647✔
473
const ≥ = >=
474

475
# this definition allows Number types to implement < instead of isless,
476
# which is more idiomatic:
477
isless(x::Real, y::Real) = x<y
1,301,281,823✔
478

479
"""
480
    cmp(x,y)
481

482
Return -1, 0, or 1 depending on whether `x` is less than, equal to, or greater than `y`,
483
respectively. Uses the total order implemented by `isless`.
484

485
# Examples
486
```jldoctest
487
julia> cmp(1, 2)
488
-1
489

490
julia> cmp(2, 1)
491
1
492

493
julia> cmp(2+im, 3-im)
494
ERROR: MethodError: no method matching isless(::Complex{Int64}, ::Complex{Int64})
495
[...]
496
```
497
"""
498
cmp(x, y) = isless(x, y) ? -1 : ifelse(isless(y, x), 1, 0)
45✔
499

500
"""
501
    cmp(<, x, y)
502

503
Return -1, 0, or 1 depending on whether `x` is less than, equal to, or greater than `y`,
504
respectively. The first argument specifies a less-than comparison function to use.
505
"""
506
cmp(<, x, y) = (x < y) ? -1 : ifelse(y < x, 1, 0)
5✔
507

508
# cmp returns -1, 0, +1 indicating ordering
509
cmp(x::Integer, y::Integer) = ifelse(isless(x, y), -1, ifelse(isless(y, x), 1, 0))
8,354✔
510

511
"""
512
    max(x, y, ...)
513

514
Return the maximum of the arguments, with respect to [`isless`](@ref).
515
If any of the arguments is [`missing`](@ref), return `missing`.
516
See also the [`maximum`](@ref) function to take the maximum element from a collection.
517

518
# Examples
519
```jldoctest
520
julia> max(2, 5, 1)
521
5
522

523
julia> max(5, missing, 6)
524
missing
525
```
526
"""
527
max(x, y) = ifelse(isless(y, x), x, y)
808,817✔
528

529
"""
530
    min(x, y, ...)
531

532
Return the minimum of the arguments, with respect to [`isless`](@ref).
533
If any of the arguments is [`missing`](@ref), return `missing`.
534
See also the [`minimum`](@ref) function to take the minimum element from a collection.
535

536
# Examples
537
```jldoctest
538
julia> min(2, 5, 1)
539
1
540

541
julia> min(4, missing, 6)
542
missing
543
```
544
"""
545
min(x,y) = ifelse(isless(y, x), y, x)
808,673✔
546

547
"""
548
    minmax(x, y)
549

550
Return `(min(x,y), max(x,y))`.
551

552
See also [`extrema`](@ref) that returns `(minimum(x), maximum(x))`.
553

554
# Examples
555
```jldoctest
556
julia> minmax('c','b')
557
('b', 'c')
558
```
559
"""
560
minmax(x,y) = isless(y, x) ? (y, x) : (x, y)
16✔
561

562
## definitions providing basic traits of arithmetic operators ##
563

564
"""
565
    identity(x)
566

567
The identity function. Returns its argument.
568

569
See also: [`one`](@ref), [`oneunit`](@ref), and [`LinearAlgebra`](@ref man-linalg)'s `I`.
570

571
# Examples
572
```jldoctest
573
julia> identity("Well, what did you expect?")
574
"Well, what did you expect?"
575
```
576
"""
577
identity(@nospecialize x) = x
77,750,677✔
578

579
+(x::Number) = x
48,145✔
580
*(x::Number) = x
55,102,281✔
581
(&)(x::Integer) = x
5,325✔
582
(|)(x::Integer) = x
7,057✔
583
xor(x::Integer) = x
3,530✔
584

585
const ⊻ = xor
586
const ⊼ = nand
587
const ⊽ = nor
588

589
# foldl for argument lists. expand fully up to a point, then
590
# switch to a loop. this allows small cases like `a+b+c+d` to be managed
591
# efficiently, without a major slowdown for `+(x...)` when `x` is big.
592
# n.b.: keep this method count small, so it can be inferred without hitting the
593
# method count limit in inference
594
afoldl(op, a) = a
49,430,670✔
595
function afoldl(op, a, bs...)
11,681✔
596
    @_terminates_locally_meta
53,411,667✔
597
    l = length(bs)
53,411,667✔
598
    i =  0; y = a;            l == i && return y
53,411,672✔
599
    #@nexprs 31 i -> (y = op(y, bs[i]); l == i && return y)
600
    i =  1; y = op(y, bs[i]); l == i && return y
59,113,853✔
601
    i =  2; y = op(y, bs[i]); l == i && return y
46,428,444✔
602
    i =  3; y = op(y, bs[i]); l == i && return y
9,055,790✔
603
    i =  4; y = op(y, bs[i]); l == i && return y
8,831,938✔
604
    i =  5; y = op(y, bs[i]); l == i && return y
8,779,252✔
605
    i =  6; y = op(y, bs[i]); l == i && return y
8,755,173✔
606
    i =  7; y = op(y, bs[i]); l == i && return y
15,961✔
607
    i =  8; y = op(y, bs[i]); l == i && return y
11,058✔
608
    i =  9; y = op(y, bs[i]); l == i && return y
3,229✔
609
    i = 10; y = op(y, bs[i]); l == i && return y
2,009✔
610
    i = 11; y = op(y, bs[i]); l == i && return y
396✔
611
    i = 12; y = op(y, bs[i]); l == i && return y
374✔
612
    i = 13; y = op(y, bs[i]); l == i && return y
101✔
613
    i = 14; y = op(y, bs[i]); l == i && return y
76✔
614
    i = 15; y = op(y, bs[i]); l == i && return y
68✔
615
    i = 16; y = op(y, bs[i]); l == i && return y
66✔
616
    i = 17; y = op(y, bs[i]); l == i && return y
58✔
617
    i = 18; y = op(y, bs[i]); l == i && return y
57✔
618
    i = 19; y = op(y, bs[i]); l == i && return y
56✔
619
    i = 20; y = op(y, bs[i]); l == i && return y
51✔
620
    i = 21; y = op(y, bs[i]); l == i && return y
47✔
621
    i = 22; y = op(y, bs[i]); l == i && return y
42✔
622
    i = 23; y = op(y, bs[i]); l == i && return y
41✔
623
    i = 24; y = op(y, bs[i]); l == i && return y
39✔
624
    i = 25; y = op(y, bs[i]); l == i && return y
38✔
625
    i = 26; y = op(y, bs[i]); l == i && return y
37✔
626
    i = 27; y = op(y, bs[i]); l == i && return y
36✔
627
    i = 28; y = op(y, bs[i]); l == i && return y
35✔
628
    i = 29; y = op(y, bs[i]); l == i && return y
33✔
629
    i = 30; y = op(y, bs[i]); l == i && return y
30✔
630
    i = 31; y = op(y, bs[i]); l == i && return y
27✔
631
    for i in (i + 1):l
26✔
632
        y = op(y, bs[i])
633✔
633
    end
1,240✔
634
    return y
26✔
635
end
636
setfield!(typeof(afoldl).name, :max_args, Int32(34), :monotonic)
637

638
for op in (:+, :*, :&, :|, :xor, :min, :max, :kron)
639
    @eval begin
640
        # note: these definitions must not cause a dispatch loop when +(a,b) is
641
        # not defined, and must only try to call 2-argument definitions, so
642
        # that defining +(a,b) is sufficient for full functionality.
643
        ($op)(a, b, c, xs...) = (@inline; afoldl($op, ($op)(($op)(a,b),c), xs...))
716,886,773✔
644
        # a further concern is that it's easy for a type like (Int,Int...)
645
        # to match many definitions, so we need to keep the number of
646
        # definitions down to avoid losing type information.
647
    end
648
end
649

650
function kron! end
651

652
const var"'" = adjoint
653

654
"""
655
    \\(x, y)
656

657
Left division operator: multiplication of `y` by the inverse of `x` on the left. Gives
658
floating-point results for integer arguments.
659

660
# Examples
661
```jldoctest
662
julia> 3 \\ 6
663
2.0
664

665
julia> inv(3) * 6
666
2.0
667

668
julia> A = [4 3; 2 1]; x = [5, 6];
669

670
julia> A \\ x
671
2-element Vector{Float64}:
672
  6.5
673
 -7.0
674

675
julia> inv(A) * x
676
2-element Vector{Float64}:
677
  6.5
678
 -7.0
679
```
680
"""
681
\(x,y) = adjoint(adjoint(y)/adjoint(x))
820,456✔
682

683
# Core <<, >>, and >>> take either Int or UInt as second arg. Signed shift
684
# counts can shift in either direction, and are translated here to unsigned
685
# counts. Integer datatypes only need to implement the unsigned version.
686

687
"""
688
    <<(x, n)
689

690
Left bit shift operator, `x << n`. For `n >= 0`, the result is `x` shifted left
691
by `n` bits, filling with `0`s. This is equivalent to `x * 2^n`. For `n < 0`,
692
this is equivalent to `x >> -n`.
693

694
# Examples
695
```jldoctest
696
julia> Int8(3) << 2
697
12
698

699
julia> bitstring(Int8(3))
700
"00000011"
701

702
julia> bitstring(Int8(12))
703
"00001100"
704
```
705
See also [`>>`](@ref), [`>>>`](@ref), [`exp2`](@ref), [`ldexp`](@ref).
706
"""
707
function <<(x::Integer, c::Integer)
76✔
708
    @inline
72✔
709
    typemin(Int) <= c <= typemax(Int) && return x << (c % Int)
76✔
710
    (x >= 0 || c >= 0) && return zero(x) << 0  # for type stability
×
711
    oftype(x, -1)
×
712
end
713
function <<(x::Integer, c::Unsigned)
8✔
714
    @inline
8✔
715
    if c isa UInt
8✔
716
        throw(MethodError(<<, (x, c)))
×
717
    end
718
    c <= typemax(UInt) ? x << (c % UInt) : zero(x) << UInt(0)
8✔
719
end
720
<<(x::Integer, c::Int) = c >= 0 ? x << unsigned(c) : x >> unsigned(-c)
5,670✔
721

722
"""
723
    >>(x, n)
724

725
Right bit shift operator, `x >> n`. For `n >= 0`, the result is `x` shifted
726
right by `n` bits, filling with `0`s if `x >= 0`, `1`s if `x < 0`, preserving
727
the sign of `x`. This is equivalent to `fld(x, 2^n)`. For `n < 0`, this is
728
equivalent to `x << -n`.
729

730
# Examples
731
```jldoctest
732
julia> Int8(13) >> 2
733
3
734

735
julia> bitstring(Int8(13))
736
"00001101"
737

738
julia> bitstring(Int8(3))
739
"00000011"
740

741
julia> Int8(-14) >> 2
742
-4
743

744
julia> bitstring(Int8(-14))
745
"11110010"
746

747
julia> bitstring(Int8(-4))
748
"11111100"
749
```
750
See also [`>>>`](@ref), [`<<`](@ref).
751
"""
752
function >>(x::Integer, c::Integer)
84✔
753
    @inline
82✔
754
    if c isa UInt
82✔
755
        throw(MethodError(>>, (x, c)))
×
756
    end
757
    typemin(Int) <= c <= typemax(Int) && return x >> (c % Int)
84✔
758
    (x >= 0 || c < 0) && return zero(x) >> 0
×
759
    oftype(x, -1)
×
760
end
761
>>(x::Integer, c::Int) = c >= 0 ? x >> unsigned(c) : x << unsigned(-c)
9,221✔
762

763
"""
764
    >>>(x, n)
765

766
Unsigned right bit shift operator, `x >>> n`. For `n >= 0`, the result is `x`
767
shifted right by `n` bits, filling with `0`s. For `n < 0`, this is equivalent
768
to `x << -n`.
769

770
For [`Unsigned`](@ref) integer types, this is equivalent to [`>>`](@ref). For
771
[`Signed`](@ref) integer types, this is equivalent to `signed(unsigned(x) >> n)`.
772

773
# Examples
774
```jldoctest
775
julia> Int8(-14) >>> 2
776
60
777

778
julia> bitstring(Int8(-14))
779
"11110010"
780

781
julia> bitstring(Int8(60))
782
"00111100"
783
```
784

785
[`BigInt`](@ref)s are treated as if having infinite size, so no filling is required and this
786
is equivalent to [`>>`](@ref).
787

788
See also [`>>`](@ref), [`<<`](@ref).
789
"""
790
function >>>(x::Integer, c::Integer)
72✔
791
    @inline
72✔
792
    typemin(Int) <= c <= typemax(Int) ? x >>> (c % Int) : zero(x) >>> 0
72✔
793
end
794
function >>>(x::Integer, c::Unsigned)
8✔
795
    @inline
6,083✔
796
    if c isa UInt
6,083✔
797
        throw(MethodError(>>>, (x, c)))
×
798
    end
799
    c <= typemax(UInt) ? x >>> (c % UInt) : zero(x) >>> 0
6,083✔
800
end
801
>>>(x::Integer, c::Int) = c >= 0 ? x >>> unsigned(c) : x << unsigned(-c)
1,808✔
802

803
# operator alias
804

805
"""
806
    rem(x, y)
807
    %(x, y)
808

809
Remainder from Euclidean division, returning a value of the same sign as `x`, and smaller in
810
magnitude than `y`. This value is always exact.
811

812
See also: [`div`](@ref), [`mod`](@ref), [`mod1`](@ref), [`divrem`](@ref).
813

814
# Examples
815
```jldoctest
816
julia> x = 15; y = 4;
817

818
julia> x % y
819
3
820

821
julia> x == div(x, y) * y + rem(x, y)
822
true
823

824
julia> rem.(-5:5, 3)'
825
1×11 adjoint(::Vector{Int64}) with eltype Int64:
826
 -2  -1  0  -2  -1  0  1  2  0  1  2
827
```
828
"""
829
rem
830
const % = rem
831

832
"""
833
    div(x, y)
834
    ÷(x, y)
835

836
The quotient from Euclidean (integer) division. Generally equivalent
837
to a mathematical operation x/y without a fractional part.
838

839
See also: [`cld`](@ref), [`fld`](@ref), [`rem`](@ref), [`divrem`](@ref).
840

841
# Examples
842
```jldoctest
843
julia> 9 ÷ 4
844
2
845

846
julia> -5 ÷ 3
847
-1
848

849
julia> 5.0 ÷ 2
850
2.0
851

852
julia> div.(-5:5, 3)'
853
1×11 adjoint(::Vector{Int64}) with eltype Int64:
854
 -1  -1  -1  0  0  0  0  0  1  1  1
855
```
856
"""
857
div
858
const ÷ = div
859

860
"""
861
    mod1(x, y)
862

863
Modulus after flooring division, returning a value `r` such that `mod(r, y) == mod(x, y)`
864
in the range ``(0, y]`` for positive `y` and in the range ``[y,0)`` for negative `y`.
865

866
With integer arguments and positive `y`, this is equal to `mod(x, 1:y)`, and hence natural
867
for 1-based indexing. By comparison, `mod(x, y) == mod(x, 0:y-1)` is natural for computations with
868
offsets or strides.
869

870
See also [`mod`](@ref), [`fld1`](@ref), [`fldmod1`](@ref).
871

872
# Examples
873
```jldoctest
874
julia> mod1(4, 2)
875
2
876

877
julia> mod1.(-5:5, 3)'
878
1×11 adjoint(::Vector{Int64}) with eltype Int64:
879
 1  2  3  1  2  3  1  2  3  1  2
880

881
julia> mod1.([-0.1, 0, 0.1, 1, 2, 2.9, 3, 3.1]', 3)
882
1×8 Matrix{Float64}:
883
 2.9  3.0  0.1  1.0  2.0  2.9  3.0  0.1
884
```
885
"""
886
mod1(x::T, y::T) where {T<:Real} = (m = mod(x, y); ifelse(m == 0, y, m))
1,422,329✔
887

888

889
"""
890
    fld1(x, y)
891

892
Flooring division, returning a value consistent with `mod1(x,y)`
893

894
See also [`mod1`](@ref), [`fldmod1`](@ref).
895

896
# Examples
897
```jldoctest
898
julia> x = 15; y = 4;
899

900
julia> fld1(x, y)
901
4
902

903
julia> x == fld(x, y) * y + mod(x, y)
904
true
905

906
julia> x == (fld1(x, y) - 1) * y + mod1(x, y)
907
true
908
```
909
"""
910
fld1(x::T, y::T) where {T<:Real} = (m = mod1(x, y); fld((x - m) + y, y))
1,263✔
911
function fld1(x::T, y::T) where T<:Integer
3,024✔
912
    d = div(x, y)
3,058✔
913
    return d + (!signbit(x ⊻ y) & (d * y != x))
3,054✔
914
end
915

916
"""
917
    fldmod1(x, y)
918

919
Return `(fld1(x,y), mod1(x,y))`.
920

921
See also [`fld1`](@ref), [`mod1`](@ref).
922
"""
923
fldmod1(x, y) = (fld1(x, y), mod1(x, y))
13✔
924

925

926
"""
927
    widen(x)
928

929
If `x` is a type, return a "larger" type, defined so that arithmetic operations
930
`+` and `-` are guaranteed not to overflow nor lose precision for any combination
931
of values that type `x` can hold.
932

933
For fixed-size integer types less than 128 bits, `widen` will return a type with
934
twice the number of bits.
935

936
If `x` is a value, it is converted to `widen(typeof(x))`.
937

938
# Examples
939
```jldoctest
940
julia> widen(Int32)
941
Int64
942

943
julia> widen(1.5f0)
944
1.5
945
```
946
"""
947
widen(x::T) where {T} = convert(widen(T), x)
452,037,141✔
948
widen(x::Type{T}) where {T} = throw(MethodError(widen, (T,)))
1✔
949
widen(x::Type{Union{}}, slurp...) = throw(MethodError(widen, (Union{},)))
×
950

951
# function pipelining
952

953
"""
954
    |>(x, f)
955

956
Infix operator which applies function `f` to the argument `x`.
957
This allows `f(g(x))` to be written `x |> g |> f`.
958
When used with anonymous functions, parentheses are typically required around
959
the definition to get the intended chain.
960

961
# Examples
962
```jldoctest
963
julia> 4 |> inv
964
0.25
965

966
julia> [2, 3, 5] |> sum |> inv
967
0.1
968

969
julia> [0 1; 2 3] .|> (x -> x^2) |> sum
970
14
971
```
972
"""
973
|>(x, f) = f(x)
12,492✔
974

975
_stable_typeof(x) = typeof(x)
329,253,311✔
976
_stable_typeof(::Type{T}) where {T} = @isdefined(T) ? Type{T} : DataType
583,258✔
977

978
"""
979
    f = Returns(value)
980

981
Create a callable `f` such that `f(args...; kw...) === value` holds.
982

983
# Examples
984

985
```jldoctest
986
julia> f = Returns(42);
987

988
julia> f(1)
989
42
990

991
julia> f("hello", x=32)
992
42
993

994
julia> f.value
995
42
996
```
997

998
!!! compat "Julia 1.7"
999
    `Returns` requires at least Julia 1.7.
1000
"""
1001
struct Returns{V} <: Function
1002
    value::V
1003
    Returns{V}(value) where {V} = new{V}(value)
1✔
1004
    Returns(value) = new{_stable_typeof(value)}(value)
109,904,711✔
1005
end
1006

1007
(obj::Returns)(@nospecialize(args...); @nospecialize(kw...)) = obj.value
220,097,855✔
1008

1009
# function composition
1010

1011
"""
1012
    f ∘ g
1013

1014
Compose functions: i.e. `(f ∘ g)(args...; kwargs...)` means `f(g(args...; kwargs...))`. The `∘` symbol can be
1015
entered in the Julia REPL (and most editors, appropriately configured) by typing `\\circ<tab>`.
1016

1017
Function composition also works in prefix form: `∘(f, g)` is the same as `f ∘ g`.
1018
The prefix form supports composition of multiple functions: `∘(f, g, h) = f ∘ g ∘ h`
1019
and splatting `∘(fs...)` for composing an iterable collection of functions.
1020
The last argument to `∘` execute first.
1021

1022
!!! compat "Julia 1.4"
1023
    Multiple function composition requires at least Julia 1.4.
1024

1025
!!! compat "Julia 1.5"
1026
    Composition of one function ∘(f) requires at least Julia 1.5.
1027

1028
!!! compat "Julia 1.7"
1029
    Using keyword arguments requires at least Julia 1.7.
1030

1031
# Examples
1032
```jldoctest
1033
julia> map(uppercase∘first, ["apple", "banana", "carrot"])
1034
3-element Vector{Char}:
1035
 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
1036
 'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
1037
 'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)
1038

1039
julia> (==(6)∘length).(["apple", "banana", "carrot"])
1040
3-element BitVector:
1041
 0
1042
 1
1043
 1
1044

1045
julia> fs = [
1046
           x -> 2x
1047
           x -> x-1
1048
           x -> x/2
1049
           x -> x+1
1050
       ];
1051

1052
julia> ∘(fs...)(3)
1053
2.0
1054
```
1055
See also [`ComposedFunction`](@ref), [`!f::Function`](@ref).
1056
"""
1057
function ∘ end
1058

1059
"""
1060
    ComposedFunction{Outer,Inner} <: Function
1061

1062
Represents the composition of two callable objects `outer::Outer` and `inner::Inner`. That is
1063
```julia
1064
ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))
1065
```
1066
The preferred way to construct an instance of `ComposedFunction` is to use the composition operator [`∘`](@ref):
1067
```jldoctest
1068
julia> sin ∘ cos === ComposedFunction(sin, cos)
1069
true
1070

1071
julia> typeof(sin∘cos)
1072
ComposedFunction{typeof(sin), typeof(cos)}
1073
```
1074
The composed pieces are stored in the fields of `ComposedFunction` and can be retrieved as follows:
1075
```jldoctest
1076
julia> composition = sin ∘ cos
1077
sin ∘ cos
1078

1079
julia> composition.outer === sin
1080
true
1081

1082
julia> composition.inner === cos
1083
true
1084
```
1085
!!! compat "Julia 1.6"
1086
    ComposedFunction requires at least Julia 1.6. In earlier versions `∘` returns an anonymous function instead.
1087

1088
See also [`∘`](@ref).
1089
"""
1090
struct ComposedFunction{O,I} <: Function
1091
    outer::O
1092
    inner::I
1093
    ComposedFunction{O, I}(outer, inner) where {O, I} = new{O, I}(outer, inner)
×
1094
    ComposedFunction(outer, inner) = new{Core.Typeof(outer),Core.Typeof(inner)}(outer, inner)
1,231,904✔
1095
end
1096

1097
(c::ComposedFunction)(x...; kw...) = call_composed(unwrap_composed(c), x, kw)
43,096,799✔
1098
unwrap_composed(c::ComposedFunction) = (unwrap_composed(c.outer)..., unwrap_composed(c.inner)...)
18,913,084✔
1099
unwrap_composed(c) = (maybeconstructor(c),)
19,774,490✔
1100
call_composed(fs, x, kw) = (@inline; fs[1](call_composed(tail(fs), x, kw)))
21,656,071✔
1101
call_composed(fs::Tuple{Any}, x, kw) = fs[1](x...; kw...)
21,538,215✔
1102

1103
struct Constructor{F} <: Function end
220✔
1104
(::Constructor{F})(args...; kw...) where {F} = (@inline; F(args...; kw...))
440✔
1105
maybeconstructor(::Type{F}) where {F} = Constructor{F}()
220✔
1106
maybeconstructor(f) = f
19,015,953✔
1107

1108
∘(f) = f
2✔
1109
∘(f, g) = ComposedFunction(f, g)
1,232,056✔
1110
∘(f, g, h...) = ∘(f ∘ g, h...)
8✔
1111

1112
function show(io::IO, c::ComposedFunction)
5✔
1113
    c.outer isa ComposedFunction ? show(io, c.outer) : _showcomposed(io, c.outer)
10✔
1114
    print(io, " ∘ ")
10✔
1115
    _showcomposed(io, c.inner)
10✔
1116
end
1117

1118
#shows !f instead of (!) ∘ f when ! is the outermost function
1119
function show(io::IO, c::ComposedFunction{typeof(!)})
5✔
1120
    print(io, '!')
6✔
1121
    _showcomposed(io, c.inner)
6✔
1122
end
1123

1124
_showcomposed(io::IO, x) = show(io, x)
×
1125
#display operators like + and - inside parens
1126
_showcomposed(io::IO, f::Function) = isoperator(Symbol(f)) ? (print(io, '('); show(io, f); print(io, ')')) : show(io, f)
21✔
1127
#nesting for chained composition
1128
_showcomposed(io::IO, f::ComposedFunction) = (print(io, '('); show(io, f); print(io, ')'))
2✔
1129
#no nesting when ! is the outer function in a composition chain
1130
_showcomposed(io::IO, f::ComposedFunction{typeof(!)}) = show(io, f)
1✔
1131

1132
"""
1133
    !f::Function
1134

1135
Predicate function negation: when the argument of `!` is a function, it returns a composed function which computes the boolean negation of `f`.
1136

1137
See also [`∘`](@ref).
1138

1139
# Examples
1140
```jldoctest
1141
julia> str = "∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
1142
"∀ ε > 0, ∃ δ > 0: |x-y| < δ ⇒ |f(x)-f(y)| < ε"
1143

1144
julia> filter(isletter, str)
1145
"εδxyδfxfyε"
1146

1147
julia> filter(!isletter, str)
1148
"∀  > 0, ∃  > 0: |-| <  ⇒ |()-()| < "
1149
```
1150

1151
!!! compat "Julia 1.9"
1152
    Starting with Julia 1.9, `!f` returns a [`ComposedFunction`](@ref) instead of an anonymous function.
1153
"""
1154
!(f::Function) = (!) ∘ f
4,336✔
1155
!(f::ComposedFunction{typeof(!)}) = f.inner #allows !!f === f
4✔
1156

1157
"""
1158
    Fix{N}(f, x)
1159

1160
A type representing a partially-applied version of a function `f`, with the argument
1161
`x` fixed at position `N::Int`. In other words, `Fix{3}(f, x)` behaves similarly to
1162
`(y1, y2, y3...; kws...) -> f(y1, y2, x, y3...; kws...)`.
1163

1164
!!! compat "Julia 1.12"
1165
    This general functionality requires at least Julia 1.12, while `Fix1` and `Fix2`
1166
    are available earlier.
1167

1168
!!! note
1169
    When nesting multiple `Fix`, note that the `N` in `Fix{N}` is _relative_ to the current
1170
    available arguments, rather than an absolute ordering on the target function. For example,
1171
    `Fix{1}(Fix{2}(f, 4), 4)` fixes the first and second arg, while `Fix{2}(Fix{1}(f, 4), 4)`
1172
    fixes the first and third arg.
1173
"""
1174
struct Fix{N,F,T} <: Function
1175
    f::F
1176
    x::T
1177

1178
    function Fix{N}(f::F, x) where {N,F}
2,848✔
1179
        if !(N isa Int)
218,037,987✔
1180
            throw(ArgumentError(LazyString("expected type parameter in `Fix` to be `Int`, but got `", N, "::", typeof(N), "`")))
2✔
1181
        elseif N < 1
218,037,967✔
1182
            throw(ArgumentError(LazyString("expected `N` in `Fix{N}` to be integer greater than 0, but got ", N)))
1✔
1183
        end
1184
        new{N,_stable_typeof(f),_stable_typeof(x)}(f, x)
218,535,101✔
1185
    end
1186
end
1187

1188
function (f::Fix{N})(args::Vararg{Any,M}; kws...) where {N,M}
13✔
1189
    M < N-1 && throw(ArgumentError(LazyString("expected at least ", N-1, " arguments to `Fix{", N, "}`, but got ", M)))
11✔
1190
    return f.f(args[begin:begin+(N-2)]..., f.x, args[begin+(N-1):end]...; kws...)
10✔
1191
end
1192

1193
# Special cases for improved constant propagation
1194
(f::Fix{1})(arg; kws...) = f.f(f.x, arg; kws...)
653,393,106✔
1195
(f::Fix{2})(arg; kws...) = f.f(arg, f.x; kws...)
18,384,148✔
1196

1197
"""
1198
Alias for `Fix{1}`. See [`Fix`](@ref Base.Fix).
1199
"""
1200
const Fix1{F,T} = Fix{1,F,T}
1201

1202
"""
1203
Alias for `Fix{2}`. See [`Fix`](@ref Base.Fix).
1204
"""
1205
const Fix2{F,T} = Fix{2,F,T}
1206

1207

1208
"""
1209
    isequal(x)
1210

1211
Create a function that compares its argument to `x` using [`isequal`](@ref), i.e.
1212
a function equivalent to `y -> isequal(y, x)`.
1213

1214
The returned function is of type `Base.Fix2{typeof(isequal)}`, which can be
1215
used to implement specialized methods.
1216
"""
1217
isequal(x) = Fix2(isequal, x)
898,043✔
1218

1219
"""
1220
    ==(x)
1221

1222
Create a function that compares its argument to `x` using [`==`](@ref), i.e.
1223
a function equivalent to `y -> y == x`.
1224

1225
The returned function is of type `Base.Fix2{typeof(==)}`, which can be
1226
used to implement specialized methods.
1227
"""
1228
==(x) = Fix2(==, x)
737,022✔
1229

1230
"""
1231
    !=(x)
1232

1233
Create a function that compares its argument to `x` using [`!=`](@ref), i.e.
1234
a function equivalent to `y -> y != x`.
1235
The returned function is of type `Base.Fix2{typeof(!=)}`, which can be
1236
used to implement specialized methods.
1237

1238
!!! compat "Julia 1.2"
1239
    This functionality requires at least Julia 1.2.
1240
"""
1241
!=(x) = Fix2(!=, x)
114,138✔
1242

1243
"""
1244
    >=(x)
1245

1246
Create a function that compares its argument to `x` using [`>=`](@ref), i.e.
1247
a function equivalent to `y -> y >= x`.
1248
The returned function is of type `Base.Fix2{typeof(>=)}`, which can be
1249
used to implement specialized methods.
1250

1251
!!! compat "Julia 1.2"
1252
    This functionality requires at least Julia 1.2.
1253
"""
1254
>=(x) = Fix2(>=, x)
557✔
1255

1256
"""
1257
    <=(x)
1258

1259
Create a function that compares its argument to `x` using [`<=`](@ref), i.e.
1260
a function equivalent to `y -> y <= x`.
1261
The returned function is of type `Base.Fix2{typeof(<=)}`, which can be
1262
used to implement specialized methods.
1263

1264
!!! compat "Julia 1.2"
1265
    This functionality requires at least Julia 1.2.
1266
"""
1267
<=(x) = Fix2(<=, x)
149✔
1268

1269
"""
1270
    >(x)
1271

1272
Create a function that compares its argument to `x` using [`>`](@ref), i.e.
1273
a function equivalent to `y -> y > x`.
1274
The returned function is of type `Base.Fix2{typeof(>)}`, which can be
1275
used to implement specialized methods.
1276

1277
!!! compat "Julia 1.2"
1278
    This functionality requires at least Julia 1.2.
1279
"""
1280
>(x) = Fix2(>, x)
120,192✔
1281

1282
"""
1283
    <(x)
1284

1285
Create a function that compares its argument to `x` using [`<`](@ref), i.e.
1286
a function equivalent to `y -> y < x`.
1287
The returned function is of type `Base.Fix2{typeof(<)}`, which can be
1288
used to implement specialized methods.
1289

1290
!!! compat "Julia 1.2"
1291
    This functionality requires at least Julia 1.2.
1292
"""
1293
<(x) = Fix2(<, x)
517✔
1294

1295
"""
1296
    splat(f)
1297

1298
Equivalent to
1299
```julia
1300
    my_splat(f) = args->f(args...)
1301
```
1302
i.e. given a function returns a new function that takes one argument and splats
1303
it into the original function. This is useful as an adaptor to pass a
1304
multi-argument function in a context that expects a single argument, but passes
1305
a tuple as that single argument.
1306

1307
# Examples
1308
```jldoctest
1309
julia> map(splat(+), zip(1:3,4:6))
1310
3-element Vector{Int64}:
1311
 5
1312
 7
1313
 9
1314

1315
julia> my_add = splat(+)
1316
splat(+)
1317

1318
julia> my_add((1,2,3))
1319
6
1320
```
1321
"""
1322
splat(f) = Splat(f)
279✔
1323

1324
"""
1325
    Base.Splat{F} <: Function
1326

1327
Represents a splatted function. That is
1328
```julia
1329
Base.Splat(f)(args) === f(args...)
1330
```
1331
The preferred way to construct an instance of `Base.Splat` is to use the [`splat`](@ref) function.
1332

1333
!!! compat "Julia 1.9"
1334
    Splat requires at least Julia 1.9. In earlier versions `splat` returns an anonymous function instead.
1335

1336
See also [`splat`](@ref).
1337
"""
1338
struct Splat{F} <: Function
1339
    f::F
1340
    Splat(f) = new{Core.Typeof(f)}(f)
279✔
1341
end
1342
(s::Splat)(args) = s.f(args...)
590,452✔
1343
show(io::IO, s::Splat) = (print(io, "splat("); show(io, s.f); print(io, ")"))
×
1344

1345
## in and related operators
1346

1347
"""
1348
    in(collection)
1349
    ∈(collection)
1350

1351
Create a function that checks whether its argument is [`in`](@ref) `collection`, i.e.
1352
a function equivalent to `y -> y in collection`. See also [`insorted`](@ref) for use
1353
with sorted collections.
1354

1355
The returned function is of type `Base.Fix2{typeof(in)}`, which can be
1356
used to implement specialized methods.
1357
"""
1358
in(x) = Fix2(in, x)
41,379✔
1359

1360
function in(x, itr::Any)
7,034✔
1361
    anymissing = false
1,254,287✔
1362
    for y in itr
3,580,696✔
1363
        v = (y == x)
2,147,483,647✔
1364
        if ismissing(v)
6,468,432✔
1365
            anymissing = true
3✔
1366
        elseif v
2,147,483,647✔
1367
            return true
2,520,890✔
1368
        end
1369
    end
2,147,483,647✔
1370
    return anymissing ? missing : false
1,052,409✔
1371
end
1372

1373
# Specialized variant of in for Tuple, which can generate typed comparisons for each element
1374
# of the tuple, skipping values that are statically known to be != at compile time.
1375
in(x, itr::Tuple) = _in_tuple(x, itr, false)
383,290,174✔
1376
# This recursive function will be unrolled at compiletime, and will not generate separate
1377
# llvm-compiled specializations for each step of the recursion.
1378
function _in_tuple(x, @nospecialize(itr::Tuple), anymissing::Bool)
7,255✔
1379
    @inline
387,292,260✔
1380
    # Base case
1381
    if isempty(itr)
387,295,423✔
1382
        return anymissing ? missing : false
238,503,998✔
1383
    end
1384
    # Recursive case
1385
    v = (itr[1] == x)
149,153,472✔
1386
    if ismissing(v)
148,876,405✔
1387
        anymissing = true
×
1388
    elseif v
149,100,390✔
1389
        return true
2,971,022✔
1390
    end
1391
    return _in_tuple(x, tail(itr), anymissing)
146,183,329✔
1392
end
1393

1394
# fallback to the loop implementation after some number of arguments to avoid inference blowup
1395
in(x, itr::Any32) = invoke(in, Tuple{Any,Any}, x, itr)
×
1396

1397
const ∈ = in
1398
∉(x, itr) = !∈(x, itr)
2,196,917✔
1399
∉(itr) = Fix2(∉, itr)
30✔
1400

1401
"""
1402
    ∋(collection, item)::Bool
1403

1404
Like [`in`](@ref), but with arguments in reverse order.
1405
Avoid adding methods to this function; define `in` instead.
1406
"""
1407
∋(itr, x) = in(x, itr)
24✔
1408

1409
"""
1410
    ∋(item)
1411

1412
Create a function that checks whether its argument contains the given `item`, i.e.
1413
a function equivalent to `y -> item in y`.
1414

1415
!!! compat "Julia 1.6"
1416
    This method requires Julia 1.6 or later.
1417
"""
1418
∋(x) = Fix2(∋, x)
3✔
1419

1420
∌(itr, x) = !∋(itr, x)
3✔
1421
∌(x) = Fix2(∌, x)
1✔
1422

1423
"""
1424
    in(item, collection)::Bool
1425
    ∈(item, collection)::Bool
1426

1427
Determine whether an item is in the given collection, in the sense that it is
1428
[`==`](@ref) to one of the values generated by iterating over the collection.
1429
Can equivalently be used with infix syntax:
1430

1431
    item in collection
1432
    item ∈ collection
1433

1434
Return a `Bool` value, except if `item` is [`missing`](@ref) or `collection`
1435
contains `missing` but not `item`, in which case `missing` is returned
1436
([three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic),
1437
matching the behavior of [`any`](@ref) and [`==`](@ref)).
1438
Some collections follow a slightly different definition. For example,
1439
[`Set`](@ref)s check whether the item [`isequal`](@ref) to one of the elements;
1440
[`Dict`](@ref)s look for `key=>value` pairs, and the `key` is compared using
1441
[`isequal`](@ref).
1442

1443
To test for the presence of a key in a dictionary, use [`haskey`](@ref)
1444
or `k in keys(dict)`. For the collections mentioned above,
1445
the result is always a `Bool`.
1446

1447
When broadcasting with `in.(items, collection)` or `items .∈ collection`, both
1448
`items` and `collection` are broadcasted over, which is often not what is intended.
1449
For example, if both arguments are vectors (and the dimensions match), the result is
1450
a vector indicating whether each value in collection `items` is `in` the value at the
1451
corresponding position in `collection`. To get a vector indicating whether each value
1452
in `items` is in `collection`, wrap `collection` in a tuple or a `Ref` like this:
1453
`in.(items, Ref(collection))` or `items .∈ Ref(collection)`.
1454

1455
See also: [`∉`](@ref), [`insorted`](@ref), [`contains`](@ref), [`occursin`](@ref), [`issubset`](@ref).
1456

1457
# Examples
1458
```jldoctest
1459
julia> a = 1:3:20
1460
1:3:19
1461

1462
julia> 4 in a
1463
true
1464

1465
julia> 5 in a
1466
false
1467

1468
julia> missing in [1, 2]
1469
missing
1470

1471
julia> 1 in [2, missing]
1472
missing
1473

1474
julia> 1 in [1, missing]
1475
true
1476

1477
julia> missing in Set([1, 2])
1478
false
1479

1480
julia> (1=>missing) in Dict(1=>10, 2=>20)
1481
missing
1482

1483
julia> [1, 2] .∈ [2, 3]
1484
2-element BitVector:
1485
 0
1486
 0
1487

1488
julia> [1, 2] .∈ ([2, 3],)
1489
2-element BitVector:
1490
 0
1491
 1
1492
```
1493
"""
1494
in
1495

1496
"""
1497
    ∉(item, collection)::Bool
1498
    ∌(collection, item)::Bool
1499

1500
Negation of `∈` and `∋`, i.e. checks that `item` is not in `collection`.
1501

1502
When broadcasting with `items .∉ collection`, both `items` and `collection` are
1503
broadcasted over, which is often not what is intended. For example, if both arguments
1504
are vectors (and the dimensions match), the result is a vector indicating whether
1505
each value in collection `items` is not in the value at the corresponding position
1506
in `collection`. To get a vector indicating whether each value in `items` is not in
1507
`collection`, wrap `collection` in a tuple or a `Ref` like this:
1508
`items .∉ Ref(collection)`.
1509

1510
# Examples
1511
```jldoctest
1512
julia> 1 ∉ 2:4
1513
true
1514

1515
julia> 1 ∉ 1:3
1516
false
1517

1518
julia> [1, 2] .∉ [2, 3]
1519
2-element BitVector:
1520
 1
1521
 1
1522

1523
julia> [1, 2] .∉ ([2, 3],)
1524
2-element BitVector:
1525
 1
1526
 0
1527
```
1528
"""
1529
∉, ∌
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