@@ -8,7 +8,7 @@ function diaglength(a::AbstractArray)
88 return minimum (size (a))
99end
1010
11- function isdiagindex (a:: AbstractArray{<:Any,N} , I:: CartesianIndex{N} ) where {N}
11+ @inline function isdiagindex (a:: AbstractArray{<:Any,N} , I:: CartesianIndex{N} ) where {N}
1212 @boundscheck checkbounds (a, I)
1313 return allequal (Tuple (I))
1414end
3030struct DiagCartesianIndices{N} <: AbstractVector{CartesianIndex{N}}
3131 diaglength:: Int
3232end
33- function DiagCartesianIndices (axes:: Tuple{Vararg{AbstractUnitRange}} )
33+ function DiagCartesianIndices (axes:: Tuple{AbstractUnitRange, Vararg{AbstractUnitRange}} )
3434 # Check the ranges are one-based.
3535 @assert all (isone, first .(axes))
3636 return DiagCartesianIndices {length(axes)} (minimum (length .(axes)))
3737end
38- function DiagCartesianIndices (dims:: Tuple{Vararg{Int}} )
38+ function DiagCartesianIndices (dims:: Tuple{Int, Vararg{Int}} )
3939 return DiagCartesianIndices (Base. OneTo .(dims))
4040end
41+ function DiagCartesianIndices (dims:: Tuple{} )
42+ return DiagCartesianIndices {0} (0 )
43+ end
4144function DiagCartesianIndices (a:: AbstractArray )
4245 return DiagCartesianIndices (axes (a))
4346end
@@ -46,19 +49,31 @@ function Base.getindex(I::DiagCartesianIndices{N}, i::Int) where {N}
4649 return CartesianIndex (ntuple (Returns (i), N))
4750end
4851
52+ function checkdiagbounds (:: Type{Bool} , a:: AbstractArray , i:: Integer )
53+ Base. require_one_based_indexing (a)
54+ return i ∈ 1 : diaglength (a)
55+ end
56+ function checkdiagbounds (a:: AbstractArray , i:: Integer )
57+ checkdiagbounds (Bool, a, i) || throw (BoundsError (a, ntuple (Returns (i), ndims (a))))
58+ return nothing
59+ end
60+
61+ # Convert a linear index along the diagonal to the corresponding
62+ # CartesianIndex.
63+ @inline function diagindex (a:: AbstractArray , i:: Integer )
64+ @boundscheck checkdiagbounds (a, i)
65+ return CartesianIndex (ntuple (Returns (i), ndims (a)))
66+ end
67+
4968function diagindices (a:: AbstractArray )
5069 return diagindices (IndexStyle (a), a)
5170end
5271function diagindices (:: IndexLinear , a:: AbstractArray )
53- maxdiag = LinearIndices (a)[CartesianIndex ( ntuple ( Returns ( diaglength (a)), ndims (a) ))]
72+ maxdiag = isempty (a) ? 0 : @inbounds LinearIndices (a)[diagindex (a, diaglength (a ))]
5473 return 1 : diagstride (a): maxdiag
5574end
5675function diagindices (:: IndexCartesian , a:: AbstractArray )
5776 return DiagCartesianIndices (a)
58- # TODO : Define a special iterator for this, i.e. `DiagCartesianIndices`?
59- return Iterators. map (
60- i -> CartesianIndex (ntuple (Returns (i), ndims (a))), Base. OneTo (diaglength (a))
61- )
6277end
6378
6479function diagindices (a:: AbstractArray{<:Any,0} )
0 commit comments