@@ -96,33 +96,8 @@ indices1(iter) = OneTo(length(iter))
96
96
unsafe_indices (A) = axes (A)
97
97
unsafe_indices (r:: AbstractRange ) = (OneTo (unsafe_length (r)),) # Ranges use checked_sub for size
98
98
99
- """
100
- linearindices(A)
101
-
102
- Return a `UnitRange` specifying the valid range of indices for `A[i]`
103
- where `i` is an `Int`. For arrays with conventional indexing (indices
104
- start at 1), or any multidimensional array, this is `1:length(A)`;
105
- however, for one-dimensional arrays with unconventional indices, this
106
- is `axes(A, 1)`.
107
-
108
- Calling this function is the "safe" way to write algorithms that
109
- exploit linear indexing.
110
-
111
- # Examples
112
- ```jldoctest
113
- julia> A = fill(1, (5,6,7));
114
-
115
- julia> b = linearindices(A);
116
-
117
- julia> extrema(b)
118
- (1, 210)
119
- ```
120
- """
121
- linearindices (A:: AbstractArray ) = (@_inline_meta ; OneTo (_length (A)))
122
- linearindices (A:: AbstractVector ) = (@_inline_meta ; indices1 (A))
123
-
124
99
keys (a:: AbstractArray ) = CartesianIndices (axes (a))
125
- keys (a:: AbstractVector ) = linearindices (a)
100
+ keys (a:: AbstractVector ) = LinearIndices (a)
126
101
127
102
prevind (:: AbstractArray , i:: Integer ) = Int (i)- 1
128
103
nextind (:: AbstractArray , i:: Integer ) = Int (i)+ 1
@@ -187,7 +162,7 @@ julia> lastindex(rand(3,4,5), 2)
187
162
4
188
163
```
189
164
"""
190
- lastindex (a:: AbstractArray ) = (@_inline_meta ; last (linearindices (a)))
165
+ lastindex (a:: AbstractArray ) = (@_inline_meta ; last (LinearIndices (a)))
191
166
lastindex (a:: AbstractArray , d) = (@_inline_meta ; last (axes (a, d)))
192
167
193
168
"""
@@ -205,7 +180,7 @@ julia> firstindex(rand(3,4,5), 2)
205
180
1
206
181
```
207
182
"""
208
- firstindex (a:: AbstractArray ) = (@_inline_meta ; first (linearindices (a)))
183
+ firstindex (a:: AbstractArray ) = (@_inline_meta ; first (LinearIndices (a)))
209
184
firstindex (a:: AbstractArray , d) = (@_inline_meta ; first (axes (a, d)))
210
185
211
186
first (a:: AbstractArray ) = a[first (eachindex (a))]
@@ -321,49 +296,6 @@ function trailingsize(inds::Indices)
321
296
prod (map (unsafe_length, inds))
322
297
end
323
298
324
- # # Traits for array types ##
325
-
326
- abstract type IndexStyle end
327
- struct IndexLinear <: IndexStyle end
328
- struct IndexCartesian <: IndexStyle end
329
-
330
- """
331
- IndexStyle(A)
332
- IndexStyle(typeof(A))
333
-
334
- `IndexStyle` specifies the "native indexing style" for array `A`. When
335
- you define a new `AbstractArray` type, you can choose to implement
336
- either linear indexing or cartesian indexing. If you decide to
337
- implement linear indexing, then you must set this trait for your array
338
- type:
339
-
340
- Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()
341
-
342
- The default is `IndexCartesian()`.
343
-
344
- Julia's internal indexing machinery will automatically (and invisibly)
345
- convert all indexing operations into the preferred style. This allows users
346
- to access elements of your array using any indexing style, even when explicit
347
- methods have not been provided.
348
-
349
- If you define both styles of indexing for your `AbstractArray`, this
350
- trait can be used to select the most performant indexing style. Some
351
- methods check this trait on their inputs, and dispatch to different
352
- algorithms depending on the most efficient access pattern. In
353
- particular, [`eachindex`](@ref) creates an iterator whose type depends
354
- on the setting of this trait.
355
- """
356
- IndexStyle (A:: AbstractArray ) = IndexStyle (typeof (A))
357
- IndexStyle (:: Type{Union{}} ) = IndexLinear ()
358
- IndexStyle (:: Type{<:AbstractArray} ) = IndexCartesian ()
359
- IndexStyle (:: Type{<:Array} ) = IndexLinear ()
360
- IndexStyle (:: Type{<:AbstractRange} ) = IndexLinear ()
361
-
362
- IndexStyle (A:: AbstractArray , B:: AbstractArray ) = IndexStyle (IndexStyle (A), IndexStyle (B))
363
- IndexStyle (A:: AbstractArray , B:: AbstractArray... ) = IndexStyle (IndexStyle (A), IndexStyle (B... ))
364
- IndexStyle (:: IndexLinear , :: IndexLinear ) = IndexLinear ()
365
- IndexStyle (:: IndexStyle , :: IndexStyle ) = IndexCartesian ()
366
-
367
299
# # Bounds checking ##
368
300
369
301
# The overall hierarchy is
@@ -411,10 +343,11 @@ function checkbounds(::Type{Bool}, A::AbstractArray, I...)
411
343
@_inline_meta
412
344
checkbounds_indices (Bool, axes (A), I)
413
345
end
346
+
414
347
# Linear indexing is explicitly allowed when there is only one (non-cartesian) index
415
348
function checkbounds (:: Type{Bool} , A:: AbstractArray , i)
416
349
@_inline_meta
417
- checkindex (Bool, linearindices ( A), i)
350
+ checkindex (Bool, eachindex ( IndexLinear (), A), i)
418
351
end
419
352
# As a special extension, allow using logical arrays that match the source array exactly
420
353
function checkbounds (:: Type{Bool} , A:: AbstractArray{<:Any,N} , I:: AbstractArray{Bool,N} ) where N
@@ -674,7 +607,7 @@ function copyto!(dest::AbstractArray, dstart::Integer, src, sstart::Integer, n::
674
607
n < 0 && throw (ArgumentError (string (" tried to copy n=" , n, " elements, but n should be nonnegative" )))
675
608
n == 0 && return dest
676
609
dmax = dstart + n - 1
677
- inds = linearindices (dest)
610
+ inds = LinearIndices (dest)
678
611
if (dstart ∉ inds || dmax ∉ inds) | (sstart < 1 )
679
612
sstart < 1 && throw (ArgumentError (string (" source start offset (" ,sstart," ) is < 1" )))
680
613
throw (BoundsError (dest, dstart: dmax))
@@ -704,7 +637,7 @@ copyto!(dest::AbstractArray, src::AbstractArray) =
704
637
copyto! (IndexStyle (dest), dest, IndexStyle (src), src)
705
638
706
639
function copyto! (:: IndexStyle , dest:: AbstractArray , :: IndexStyle , src:: AbstractArray )
707
- destinds, srcinds = linearindices (dest), linearindices (src)
640
+ destinds, srcinds = LinearIndices (dest), LinearIndices (src)
708
641
isempty (srcinds) || (first (srcinds) ∈ destinds && last (srcinds) ∈ destinds) ||
709
642
throw (BoundsError (dest, srcinds))
710
643
@inbounds for i in srcinds
@@ -714,7 +647,7 @@ function copyto!(::IndexStyle, dest::AbstractArray, ::IndexStyle, src::AbstractA
714
647
end
715
648
716
649
function copyto! (:: IndexStyle , dest:: AbstractArray , :: IndexCartesian , src:: AbstractArray )
717
- destinds, srcinds = linearindices (dest), linearindices (src)
650
+ destinds, srcinds = LinearIndices (dest), LinearIndices (src)
718
651
isempty (srcinds) || (first (srcinds) ∈ destinds && last (srcinds) ∈ destinds) ||
719
652
throw (BoundsError (dest, srcinds))
720
653
i = 0
@@ -725,11 +658,11 @@ function copyto!(::IndexStyle, dest::AbstractArray, ::IndexCartesian, src::Abstr
725
658
end
726
659
727
660
function copyto! (dest:: AbstractArray , dstart:: Integer , src:: AbstractArray )
728
- copyto! (dest, dstart, src, first (linearindices (src)), _length (src))
661
+ copyto! (dest, dstart, src, first (LinearIndices (src)), _length (src))
729
662
end
730
663
731
664
function copyto! (dest:: AbstractArray , dstart:: Integer , src:: AbstractArray , sstart:: Integer )
732
- srcinds = linearindices (src)
665
+ srcinds = LinearIndices (src)
733
666
sstart ∈ srcinds || throw (BoundsError (src, sstart))
734
667
copyto! (dest, dstart, src, sstart, last (srcinds)- sstart+ 1 )
735
668
end
@@ -739,7 +672,7 @@ function copyto!(dest::AbstractArray, dstart::Integer,
739
672
n:: Integer )
740
673
n == 0 && return dest
741
674
n < 0 && throw (ArgumentError (string (" tried to copy n=" , n, " elements, but n should be nonnegative" )))
742
- destinds, srcinds = linearindices (dest), linearindices (src)
675
+ destinds, srcinds = LinearIndices (dest), LinearIndices (src)
743
676
(dstart ∈ destinds && dstart+ n- 1 ∈ destinds) || throw (BoundsError (dest, dstart: dstart+ n- 1 ))
744
677
(sstart ∈ srcinds && sstart+ n- 1 ∈ srcinds) || throw (BoundsError (src, sstart: sstart+ n- 1 ))
745
678
@inbounds for i = 0 : (n- 1 )
@@ -868,11 +801,13 @@ function eachindex(A::AbstractArray, B::AbstractArray...)
868
801
@_inline_meta
869
802
eachindex (IndexStyle (A,B... ), A, B... )
870
803
end
871
- eachindex (:: IndexLinear , A:: AbstractArray ) = linearindices (A)
804
+ eachindex (:: IndexLinear , A:: AbstractArray ) = (@_inline_meta ; OneTo (_length (A)))
805
+ eachindex (:: IndexLinear , A:: AbstractVector ) = (@_inline_meta ; indices1 (A))
872
806
function eachindex (:: IndexLinear , A:: AbstractArray , B:: AbstractArray... )
873
807
@_inline_meta
874
- indsA = linearindices (A)
875
- _all_match_first (linearindices, indsA, B... ) || throw_eachindex_mismatch (IndexLinear (), A, B... )
808
+ indsA = eachindex (IndexLinear (), A)
809
+ _all_match_first (X-> eachindex (IndexLinear (), X), indsA, B... ) ||
810
+ throw_eachindex_mismatch (IndexLinear (), A, B... )
876
811
indsA
877
812
end
878
813
function _all_match_first (f:: F , inds, A, B... ) where F<: Function
911
846
pointer (x:: AbstractArray{T} ) where {T} = unsafe_convert (Ptr{T}, x)
912
847
function pointer (x:: AbstractArray{T} , i:: Integer ) where T
913
848
@_inline_meta
914
- unsafe_convert (Ptr{T}, x) + (i - first (linearindices (x)))* elsize (x)
849
+ unsafe_convert (Ptr{T}, x) + (i - first (LinearIndices (x)))* elsize (x)
915
850
end
916
851
917
852
# # Approach:
@@ -2025,7 +1960,7 @@ end
2025
1960
@inline ith_all (i, as) = (as[1 ][i], ith_all (i, tail (as))... )
2026
1961
2027
1962
function map_n! (f:: F , dest:: AbstractArray , As) where F
2028
- for i = linearindices (As[1 ])
1963
+ for i = LinearIndices (As[1 ])
2029
1964
dest[i] = f (ith_all (i, As)... )
2030
1965
end
2031
1966
return dest
0 commit comments