@@ -137,6 +137,8 @@ is equivalent to `buffer[inds...]`. If `check` is `false`, then all indexing arg
137
137
considered in-bounds. The default value for `check` is `true`, requiring bounds checking for
138
138
each index.
139
139
140
+ See also [`SetIndex!`](@ref)
141
+
140
142
!!! Warning
141
143
Passing `false` as `check` may result in incorrect results/crashes/corruption for
142
144
out-of-bounds indices, similar to inappropriate use of `@inbounds`. The user is
@@ -145,10 +147,10 @@ each index.
145
147
# Examples
146
148
147
149
```julia
148
- julia> ArrayInterfaceCore.GetIndex(1:10)[3]
150
+ julia> ArrayInterfaceCore.GetIndex(1:10)(3)
149
151
3
150
152
151
- julia> ArrayInterfaceCore.GetIndex{false}(1:10)[11] # shouldn't be in-bounds
153
+ julia> ArrayInterfaceCore.GetIndex{false}(1:10)(11) # shouldn't be in-bounds
152
154
11
153
155
154
156
```
@@ -163,10 +165,52 @@ struct GetIndex{CB,B} <: Function
163
165
GetIndex (b) = GetIndex {true} (b)
164
166
end
165
167
166
- buffer (g:: GetIndex ) = getfield (g, :buffer )
168
+ """
169
+ SetIndex!(buffer) = SetIndex!{true}(buffer)
170
+ SetIndex!{check}(buffer) -> g
171
+
172
+ Wraps an indexable buffer in a function type that sets a value at an index when called, so
173
+ that `g(val, inds..)` is equivalent to `setindex!(buffer, val, inds...)`. If `check` is
174
+ `false`, then all indexing arguments are considered in-bounds. The default value for `check`
175
+ is `true`, requiring bounds checking for each index.
176
+
177
+ See also [`GetIndex`](@ref)
178
+
179
+ !!! Warning
180
+ Passing `false` as `check` may result in incorrect results/crashes/corruption for
181
+ out-of-bounds indices, similar to inappropriate use of `@inbounds`. The user is
182
+ responsible for ensuring this is correctly used.
183
+
184
+ # Examples
185
+
186
+ ```julia
187
+
188
+ julia> x = [1, 2, 3, 4];
189
+
190
+ julia> ArrayInterface.SetIndex!(x)(10, 2);
191
+
192
+ julia> x[2]
193
+ 10
194
+
195
+ ```
196
+ """
197
+ struct SetIndex!{CB,B} <: Function
198
+ buffer:: B
199
+
200
+ SetIndex! {true,B} (b) where {B} = new {true,B} (b)
201
+ SetIndex! {false,B} (b) where {B} = new {false,B} (b)
202
+ SetIndex! {check} (b:: B ) where {check,B} = SetIndex! {check,B} (b)
203
+ SetIndex! (b) = SetIndex! {true} (b)
204
+ end
205
+
206
+ buffer (x:: Union{SetIndex!,GetIndex} ) = getfield (x, :buffer )
167
207
168
208
Base. @propagate_inbounds @inline (g:: GetIndex{true} )(inds... ) = buffer (g)[inds... ]
169
209
@inline (g:: GetIndex{false} )(inds... ) = @inbounds (buffer (g)[inds... ])
210
+ Base. @propagate_inbounds @inline function (s:: SetIndex!{true} )(v, inds... )
211
+ setindex! (buffer (s), v, inds... )
212
+ end
213
+ @inline (s:: SetIndex!{false} )(v, inds... ) = @inbounds (setindex! (buffer (s), v, inds... ))
170
214
171
215
"""
172
216
can_change_size(::Type{T}) -> Bool
@@ -520,6 +564,7 @@ const MatrixIndex = ArrayIndex{2}
520
564
521
565
const VectorIndex = ArrayIndex{1 }
522
566
567
+ Base. ndims (:: ArrayIndex{N} ) where {N} = N
523
568
Base. ndims (:: Type{<:ArrayIndex{N}} ) where {N} = N
524
569
525
570
struct BidiagonalIndex <: MatrixIndex
@@ -628,6 +673,7 @@ known_step(@nospecialize T::Type{<:AbstractUnitRange}) = 1
628
673
629
674
"""
630
675
is_splat_index(::Type{T}) -> Bool
676
+
631
677
Returns `static(true)` if `T` is a type that splats across multiple dimensions.
632
678
"""
633
679
is_splat_index (T:: Type ) = false
@@ -636,9 +682,24 @@ is_splat_index(@nospecialize(x)) = is_splat_index(typeof(x))
636
682
"""
637
683
ndims_index(::Type{I}) -> Int
638
684
639
- Returns the number of dimension that an instance of `I` maps to when indexing. For example,
640
- `CartesianIndex{3}` maps to 3 dimensions. If this method is not explicitly defined, then `1`
641
- is returned.
685
+ Returns the number of dimensions that an instance of `I` indexes into. If this method is
686
+ not explicitly defined, then `1` is returned.
687
+
688
+ See also [`ndims_shape`](@ref)
689
+
690
+ # Examples
691
+
692
+ ```julia
693
+ julia> ArrayInterfaceCore.ndims_index(Int)
694
+ 1
695
+
696
+ julia> ArrayInterfaceCore.ndims_index(CartesianIndex(1, 2, 3))
697
+ 3
698
+
699
+ julia> ArrayInterfaceCore.ndims_index([CartesianIndex(1, 2), CartesianIndex(1, 3)])
700
+ 2
701
+
702
+ ```
642
703
"""
643
704
ndims_index (:: Type{<:Base.AbstractCartesianIndex{N}} ) where {N} = N
644
705
# preserve CartesianIndices{0} as they consume a dimension.
@@ -652,8 +713,20 @@ ndims_index(@nospecialize(i)) = ndims_index(typeof(i))
652
713
"""
653
714
ndims_shape(::Type{I}) -> Union{Int,Tuple{Vararg{Int}}}
654
715
655
- Returns the number of dimension that are represented in shape of the returned array when
716
+ Returns the number of dimension that are represented in the shape of the returned array when
656
717
indexing with an instance of `I`.
718
+
719
+ See also [`ndims_index`](@ref)
720
+
721
+ # Examples
722
+
723
+ ```julia
724
+ julia> ArrayInterfaceCore.ndims_shape([CartesianIndex(1, 1), CartesianIndex(1, 2)])
725
+ 1
726
+
727
+ julia> ndims(CartesianIndices((2,2))[[CartesianIndex(1, 1), CartesianIndex(1, 2)]])
728
+ 1
729
+
657
730
"""
658
731
ndims_shape (T:: DataType ) = ndims_index (T)
659
732
ndims_shape (:: Type{Colon} ) = 1
@@ -671,11 +744,10 @@ ndims_shape(x) = ndims_shape(typeof(x))
671
744
end
672
745
673
746
"""
674
- IndicesInfo{N}(T::Type{<:Tuple}) -> IndicesInfo{N,NI,NS }()
747
+ IndicesInfo{N}(T::Type{<:Tuple}) -> IndicesInfo{N,pdims,cdims }()
675
748
676
- Provides basic trait information for each index type in in the tuple `T`. `NI`, `NS`, and
677
- `IS` are tuples of [`ndims_index`](@ref), [`ndims_shape`](@ref), and
678
- [`is_splat_index`](@ref) (respectively) for each field of `T`.
749
+ Provides basic trait information for each index type in in the tuple `T`. `pdims` and
750
+ `cdims` are dimension mappings to the parent and child dimensions respectively.
679
751
680
752
# Examples
681
753
0 commit comments