@@ -33,17 +33,17 @@ const LoTri{T,M} = Union{LowerTriangular{T,M},UnitLowerTriangular{T,M}}
33
33
Returns the parent array that type `T` wraps.
34
34
"""
35
35
parent_type (x) = parent_type (typeof (x))
36
- parent_type (:: Type{<:SubArray{T,N,P}} ) where {T,N,P} = P
37
- parent_type (:: Type{<:Base.ReshapedArray{T,N,P}} ) where {T,N,P} = P
38
- parent_type (:: Type{Adjoint{T,S}} ) where {T,S} = S
39
- parent_type (:: Type{Transpose{T,S}} ) where {T,S} = S
40
36
parent_type (:: Type{Symmetric{T,S}} ) where {T,S} = S
41
37
parent_type (:: Type{<:AbstractTriangular{T,S}} ) where {T,S} = S
42
- parent_type (:: Type{<:PermutedDimsArray{T,N,I1,I2,A}} ) where {T,N,I1,I2,A} = A
43
- parent_type (:: Type{Base.Slice{T}} ) where {T} = T
44
- parent_type (:: Type{T} ) where {T} = T
45
- parent_type (:: Type{R} ) where {S,T,A,N,R<: Base.ReinterpretArray{T,N,S,A} } = A
38
+ parent_type (@nospecialize T:: Type{<:PermutedDimsArray} ) = fieldtype (T, :parent )
39
+ parent_type (@nospecialize T:: Type{<:Adjoint} ) = fieldtype (T, :parent )
40
+ parent_type (@nospecialize T:: Type{<:Transpose} ) = fieldtype (T, :parent )
41
+ parent_type (@nospecialize T:: Type{<:SubArray} ) = fieldtype (T, :parent )
42
+ parent_type (@nospecialize T:: Type{<:Base.ReinterpretArray} ) = fieldtype (T, :parent )
43
+ parent_type (@nospecialize T:: Type{<:Base.ReshapedArray} ) = fieldtype (T, :parent )
44
+ parent_type (@nospecialize T:: Type{<:Union{Base.Slice,Base.IdentityUnitRange}} ) = fieldtype (T, :indices )
46
45
parent_type (:: Type{Diagonal{T,V}} ) where {T,V} = V
46
+ parent_type (T:: Type ) = T
47
47
48
48
"""
49
49
buffer(x)
@@ -54,6 +54,18 @@ may not return another array type.
54
54
buffer (x) = parent (x)
55
55
buffer (x:: SparseMatrixCSC ) = getfield (x, :nzval )
56
56
buffer (x:: SparseVector ) = getfield (x, :nzval )
57
+ buffer (@nospecialize x:: Union{Base.Slice,Base.IdentityUnitRange} ) = getfield (x, :indices )
58
+
59
+ """
60
+ is_forwarding_wrapper(::Type{T}) -> Bool
61
+
62
+ Returns `true` if the type `T` wraps another data type and does not alter any of its
63
+ standard interface. For example, if `T` were an array then its size, indices, and elements
64
+ would all be equivalent to its wrapped data.
65
+ """
66
+ is_forwarding_wrapper (T:: Type ) = false
67
+ is_forwarding_wrapper (@nospecialize T:: Type{<:Base.Slice} ) = true
68
+ is_forwarding_wrapper (@nospecialize x) = is_forwarding_wrapper (typeof (x))
57
69
58
70
"""
59
71
can_change_size(::Type{T}) -> Bool
@@ -62,7 +74,9 @@ Returns `true` if the Base.size of `T` can change, in which case operations
62
74
such as `pop!` and `popfirst!` are available for collections of type `T`.
63
75
"""
64
76
can_change_size (x) = can_change_size (typeof (x))
65
- can_change_size (:: Type{T} ) where {T} = false
77
+ function can_change_size (:: Type{T} ) where {T}
78
+ is_forwarding_wrapper (T) ? can_change_size (parent_type (T)) : false
79
+ end
66
80
can_change_size (:: Type{<:Vector} ) = true
67
81
can_change_size (:: Type{<:AbstractDict} ) = true
68
82
can_change_size (:: Type{<:Base.ImmutableDict} ) = false
123
137
Query whether a type can use `setindex!`.
124
138
"""
125
139
can_setindex (x) = can_setindex (typeof (x))
126
- can_setindex (:: Type ) = true
127
- can_setindex (:: Type{<:AbstractRange} ) = false
140
+ can_setindex (T :: Type ) = is_forwarding_wrapper (T) ? can_setindex ( parent_type (T)) : true
141
+ can_setindex (@nospecialize T :: Type{<:AbstractRange} ) = false
128
142
can_setindex (:: Type{<:AbstractDict} ) = true
129
143
can_setindex (:: Type{<:Base.ImmutableDict} ) = false
130
144
can_setindex (@nospecialize T:: Type{<:Tuple} ) = false
@@ -463,15 +477,10 @@ julia> ArrayInterface.known_first(typeof(Base.OneTo(4)))
463
477
```
464
478
"""
465
479
known_first (x) = known_first (typeof (x))
466
- function known_first (:: Type{T} ) where {T}
467
- if parent_type (T) <: T
468
- return nothing
469
- else
470
- return known_first (parent_type (T))
471
- end
472
- end
473
- known_first (:: Type{Base.OneTo{T}} ) where {T} = 1
474
- known_first (:: Type{<:Base.IdentityUnitRange{T}} ) where {T} = known_first (T)
480
+ known_first (T:: Type ) = is_forwarding_wrapper (T) ? known_first (parent_type (T)) : nothing
481
+ known_first (:: Type{<:Base.OneTo} ) = 1
482
+ known_first (@nospecialize T:: Type{<:LinearIndices} ) = 1
483
+ known_first (@nospecialize T:: Type{<:Base.IdentityUnitRange} ) = known_first (parent_type (T))
475
484
function known_first (:: Type{<:CartesianIndices{N,R}} ) where {N,R}
476
485
_cartesian_index (ntuple (i -> known_first (R. parameters[i]), Val (N)))
477
486
end
@@ -483,16 +492,16 @@ If `last` of an instance of type `T` is known at compile time, return it.
483
492
Otherwise, return `nothing`.
484
493
485
494
```julia
486
- julia> ArrayInterface .known_last(typeof(1:4))
495
+ julia> ArrayInterfaceCore .known_last(typeof(1:4))
487
496
nothing
488
497
489
- julia> ArrayInterface .known_first(typeof(static(1):static(4)))
498
+ julia> ArrayInterfaceCore .known_first(typeof(static(1):static(4)))
490
499
4
491
500
492
501
```
493
502
"""
494
503
known_last (x) = known_last (typeof (x))
495
- known_last (:: Type{T} ) where {T} = parent_type (T) <: T ? nothing : known_last (parent_type (T))
504
+ known_last (T :: Type ) = is_forwarding_wrapper (T) ? known_last (parent_type (T)) : nothing
496
505
function known_last (:: Type{<:CartesianIndices{N,R}} ) where {N,R}
497
506
_cartesian_index (ntuple (i -> known_last (R. parameters[i]), Val (N)))
498
507
end
@@ -513,12 +522,12 @@ julia> ArrayInterface.known_step(typeof(1:4))
513
522
```
514
523
"""
515
524
known_step (x) = known_step (typeof (x))
516
- known_step (:: Type{T} ) where {T} = parent_type (T) <: T ? nothing : known_step (parent_type (T))
525
+ known_step (T :: Type ) = is_forwarding_wrapper (T) ? known_step (parent_type (T)) : nothing
517
526
known_step (@nospecialize T:: Type{<:AbstractUnitRange} ) = 1
518
527
519
528
"""
520
529
is_splat_index(::Type{T}) -> Bool
521
- Returns `static(true)` if `T` is a type that splats across multiple dimensions.
530
+ Returns `static(true)` if `T` is a type that splats across multiple dimensions.
522
531
"""
523
532
is_splat_index (T:: Type ) = false
524
533
is_splat_index (@nospecialize (x)) = is_splat_index (typeof (x))
@@ -536,7 +545,7 @@ ndims_index(::Type{CartesianIndices{0,Tuple{}}}) = 1
536
545
ndims_index (@nospecialize T:: Type{<:AbstractArray{Bool}} ) = ndims (T)
537
546
ndims_index (@nospecialize T:: Type{<:AbstractArray} ) = ndims_index (eltype (T))
538
547
ndims_index (@nospecialize T:: Type{<:Base.LogicalIndex} ) = ndims (fieldtype (T, :mask ))
539
- ndims_index (T:: DataType ) = 1
548
+ ndims_index (T:: Type ) = 1
540
549
ndims_index (@nospecialize (i)) = ndims_index (typeof (i))
541
550
542
551
"""
0 commit comments