@@ -1070,6 +1070,132 @@ end
10701070 replace (s, first (pat_rep), last (pat_rep), count)
10711071end
10721072
1073+ @static if VERSION < v " 0.7.0-DEV.3025"
1074+ import Base: convert, ndims, getindex, size, length, eltype,
1075+ start, next, done, first, last
1076+ export CartesianIndices, LinearIndices
1077+
1078+ struct CartesianIndices{N,R<: NTuple{N,AbstractUnitRange{Int}} } <: AbstractArray{CartesianIndex{N},N}
1079+ indices:: R
1080+ end
1081+
1082+ CartesianIndices (:: Tuple{} ) = CartesianIndices {0,typeof(())} (())
1083+ CartesianIndices (inds:: NTuple{N,AbstractUnitRange{Int}} ) where {N} =
1084+ CartesianIndices {N,typeof(inds)} (inds)
1085+ CartesianIndices (inds:: Vararg{AbstractUnitRange{Int},N} ) where {N} =
1086+ CartesianIndices (inds)
1087+ CartesianIndices (inds:: NTuple{N,AbstractUnitRange{<:Integer}} ) where {N} =
1088+ CartesianIndices (map (r-> convert (AbstractUnitRange{Int}, r), inds))
1089+ CartesianIndices (inds:: Vararg{AbstractUnitRange{<:Integer},N} ) where {N} =
1090+ CartesianIndices (inds)
1091+
1092+ CartesianIndices (index:: CartesianIndex ) = CartesianIndices (index. I)
1093+ CartesianIndices (sz:: NTuple{N,<:Integer} ) where {N} = CartesianIndices (map (Base. OneTo, sz))
1094+ CartesianIndices (inds:: NTuple{N,Union{<:Integer,AbstractUnitRange{<:Integer}}} ) where {N} =
1095+ CartesianIndices (map (i-> first (i): last (i), inds))
1096+
1097+ CartesianIndices (A:: AbstractArray ) = CartesianIndices (axes (A))
1098+
1099+ convert (:: Type{Tuple{}} , R:: CartesianIndices{0} ) = ()
1100+ convert (:: Type{NTuple{N,AbstractUnitRange{Int}}} , R:: CartesianIndices{N} ) where {N} =
1101+ R. indices
1102+
1103+ convert (:: Type{NTuple{N,AbstractUnitRange}} , R:: CartesianIndices{N} ) where {N} =
1104+ convert (NTuple{N,AbstractUnitRange{Int}}, R)
1105+ convert (:: Type{NTuple{N,UnitRange{Int}}} , R:: CartesianIndices{N} ) where {N} =
1106+ UnitRange {Int} .(convert (NTuple{N,AbstractUnitRange}, R))
1107+ convert (:: Type{NTuple{N,UnitRange}} , R:: CartesianIndices{N} ) where {N} =
1108+ UnitRange .(convert (NTuple{N,AbstractUnitRange}, R))
1109+ convert (:: Type {Tuple{Vararg{AbstractUnitRange{Int}}}}, R:: CartesianIndices{N} ) where {N} =
1110+ convert (NTuple{N,AbstractUnitRange{Int}}, R)
1111+ convert (:: Type{Tuple{Vararg{AbstractUnitRange}}} , R:: CartesianIndices ) =
1112+ convert (Tuple{Vararg{AbstractUnitRange{Int}}}, R)
1113+ convert (:: Type {Tuple{Vararg{UnitRange{Int}}}}, R:: CartesianIndices{N} ) where {N} =
1114+ convert (NTuple{N,UnitRange{Int}}, R)
1115+ convert (:: Type{Tuple{Vararg{UnitRange}}} , R:: CartesianIndices ) =
1116+ convert (Tuple{Vararg{UnitRange{Int}}}, R)
1117+
1118+ # AbstractArray implementation
1119+ Base. IndexStyle (:: Type{CartesianIndices{N,R}} ) where {N,R} = IndexCartesian ()
1120+ @inline Base. getindex (iter:: CartesianIndices{N,R} , I:: Vararg{Int, N} ) where {N,R} = CartesianIndex (first .(iter. indices) .- 1 .+ I)
1121+
1122+ ndims (R:: CartesianIndices ) = ndims (typeof (R))
1123+ ndims (:: Type{CartesianIndices{N}} ) where {N} = N
1124+ ndims (:: Type{CartesianIndices{N,TT}} ) where {N,TT} = N
1125+
1126+ eltype (R:: CartesianIndices ) = eltype (typeof (R))
1127+ eltype (:: Type{CartesianIndices{N}} ) where {N} = CartesianIndex{N}
1128+ eltype (:: Type{CartesianIndices{N,TT}} ) where {N,TT} = CartesianIndex{N}
1129+ Base. iteratorsize (:: Type{<:CartesianIndices} ) = Base. HasShape ()
1130+
1131+ @inline function start (iter:: CartesianIndices )
1132+ iterfirst, iterlast = first (iter), last (iter)
1133+ if any (map (> , iterfirst. I, iterlast. I))
1134+ return iterlast+ 1
1135+ end
1136+ iterfirst
1137+ end
1138+ @inline function next (iter:: CartesianIndices , state)
1139+ state, CartesianIndex (inc (state. I, first (iter). I, last (iter). I))
1140+ end
1141+ # increment & carry
1142+ @inline inc (:: Tuple{} , :: Tuple{} , :: Tuple{} ) = ()
1143+ @inline inc (state:: Tuple{Int} , start:: Tuple{Int} , stop:: Tuple{Int} ) = (state[1 ]+ 1 ,)
1144+ @inline function inc (state, start, stop)
1145+ if state[1 ] < stop[1 ]
1146+ return (state[1 ]+ 1 ,Base. tail (state)... )
1147+ end
1148+ newtail = inc (Base. tail (state), Base. tail (start), Base. tail (stop))
1149+ (start[1 ], newtail... )
1150+ end
1151+ @inline done (iter:: CartesianIndices , state) = state. I[end ] > last (iter. indices[end ])
1152+
1153+ # 0-d cartesian ranges are special-cased to iterate once and only once
1154+ start (iter:: CartesianIndices{0} ) = false
1155+ next (iter:: CartesianIndices{0} , state) = CartesianIndex (), true
1156+ done (iter:: CartesianIndices{0} , state) = state
1157+
1158+ size (iter:: CartesianIndices ) = map (dimlength, first (iter). I, last (iter). I)
1159+ dimlength (start, stop) = stop- start+ 1
1160+
1161+ length (iter:: CartesianIndices ) = prod (size (iter))
1162+
1163+ first (iter:: CartesianIndices ) = CartesianIndex (map (first, iter. indices))
1164+ last (iter:: CartesianIndices ) = CartesianIndex (map (last, iter. indices))
1165+
1166+ @inline function in (i:: CartesianIndex{N} , r:: CartesianIndices{N} ) where {N}
1167+ _in (true , i. I, first (r). I, last (r). I)
1168+ end
1169+ _in (b, :: Tuple{} , :: Tuple{} , :: Tuple{} ) = b
1170+ @inline _in (b, i, start, stop) = _in (b & (start[1 ] <= i[1 ] <= stop[1 ]), tail (i), tail (start), tail (stop))
1171+
1172+ struct LinearIndices{N,R<: NTuple{N,AbstractUnitRange{Int}} } <: AbstractArray{Int,N}
1173+ indices:: R
1174+ end
1175+
1176+ LinearIndices (inds:: CartesianIndices{N,R} ) where {N,R} = LinearIndices {N,R} (inds. indices)
1177+ LinearIndices (:: Tuple{} ) = LinearIndices (CartesianIndices (()))
1178+ LinearIndices (inds:: NTuple{N,AbstractUnitRange{Int}} ) where {N} = LinearIndices (CartesianIndices (inds))
1179+ LinearIndices (inds:: Vararg{AbstractUnitRange{Int},N} ) where {N} = LinearIndices (CartesianIndices (inds))
1180+ LinearIndices (inds:: NTuple{N,AbstractUnitRange{<:Integer}} ) where {N} = LinearIndices (CartesianIndices (inds))
1181+ LinearIndices (inds:: Vararg{AbstractUnitRange{<:Integer},N} ) where {N} = LinearIndices (CartesianIndices (inds))
1182+ LinearIndices (index:: CartesianIndex ) = LinearIndices (CartesianIndices (index))
1183+ LinearIndices (sz:: NTuple{N,<:Integer} ) where {N} = LinearIndices (CartesianIndices (sz))
1184+ LinearIndices (inds:: NTuple{N,Union{<:Integer,AbstractUnitRange{<:Integer}}} ) where {N} = LinearIndices (CartesianIndices (inds))
1185+ LinearIndices (A:: AbstractArray ) = LinearIndices (CartesianIndices (A))
1186+
1187+ # AbstractArray implementation
1188+ Base. IndexStyle (:: Type{LinearIndices{N,R}} ) where {N,R} = IndexCartesian ()
1189+ Compat. axes (iter:: LinearIndices{N,R} ) where {N,R} = iter. indices
1190+ @inline function Base. getindex (iter:: LinearIndices{N,R} , I:: Vararg{Int, N} ) where {N,R}
1191+ dims = length .(iter. indices)
1192+ # without the inbounds, this is slower than Base._sub2ind(iter.indices, I...)
1193+ @inbounds result = reshape (1 : prod (dims), dims)[(I .- first .(iter. indices) .+ 1 ). .. ]
1194+ return result
1195+ end
1196+ end
1197+
1198+
10731199include (" deprecated.jl" )
10741200
10751201end # module Compat
0 commit comments