Skip to content

Commit 2b991c4

Browse files
committed
Add specialized Range type, OneTo, for use with indices
1 parent 36d36b0 commit 2b991c4

File tree

4 files changed

+129
-63
lines changed

4 files changed

+129
-63
lines changed

base/abstractarray.jl

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
typealias AbstractVector{T} AbstractArray{T,1}
66
typealias AbstractMatrix{T} AbstractArray{T,2}
77
typealias AbstractVecOrMat{T} Union{AbstractVector{T}, AbstractMatrix{T}}
8-
typealias RangeIndex Union{Int, Range{Int}, UnitRange{Int}, Colon}
9-
typealias UnitRangeInteger{T<:Integer} UnitRange{T}
10-
typealias Indices{N} NTuple{N,UnitRangeInteger}
8+
typealias RangeIndex Union{Int, Range{Int}, AbstractUnitRange{Int}, Colon}
9+
typealias Indices{N} NTuple{N,AbstractUnitRange}
10+
typealias IndicesOne{N} NTuple{N,OneTo}
11+
typealias DimOrInd Union{Integer, AbstractUnitRange}
12+
typealias DimsOrInds{N} NTuple{N,DimOrInd}
1113

1214
## Basic functions ##
1315

@@ -30,20 +32,20 @@ Returns the valid range of indices for array `A` along dimension `d`.
3032
"""
3133
function indices(A::AbstractArray, d)
3234
@_inline_meta
33-
1:size(A,d)
35+
OneTo(size(A,d))
3436
end
3537
"""
3638
indices(A)
3739
3840
Returns the tuple of valid indices for array `A`.
3941
"""
40-
indices{T,N}(A::AbstractArray{T,N}) = _indices((), A)
42+
indices{T,N}(A::AbstractArray{T,N}) = _indices((), A) # faster than ntuple(d->indices(A,d), Val{N})
4143
_indices{T,N}(out::NTuple{N}, A::AbstractArray{T,N}) = out
4244
function _indices(out, A::AbstractArray)
4345
@_inline_meta
4446
_indices((out..., indices(A, length(out)+1)), A)
4547
end
46-
# This simpler implementation suffers from #16327
48+
# Note: a simpler implementation suffers from #16327
4749
# function indices{T,N}(A::AbstractArray{T,N})
4850
# @_inline_meta
4951
# ntuple(d->indices(A, d), Val{N})
@@ -203,15 +205,15 @@ Return `true` if the given `index` is within the bounds of
203205
arrays can extend this method in order to provide a specialized bounds
204206
checking implementation.
205207
"""
206-
checkindex(::Type{Bool}, inds::UnitRange, i) = throw(ArgumentError("unable to check bounds for indices of type $(typeof(i))"))
207-
checkindex(::Type{Bool}, inds::UnitRange, i::Real) = (first(inds) <= i) & (i <= last(inds))
208-
checkindex(::Type{Bool}, inds::UnitRange, ::Colon) = true
209-
function checkindex(::Type{Bool}, inds::UnitRange, r::Range)
208+
checkindex(::Type{Bool}, inds::AbstractUnitRange, i) = throw(ArgumentError("unable to check bounds for indices of type $(typeof(i))"))
209+
checkindex(::Type{Bool}, inds::AbstractUnitRange, i::Real) = (first(inds) <= i) & (i <= last(inds))
210+
checkindex(::Type{Bool}, inds::AbstractUnitRange, ::Colon) = true
211+
function checkindex(::Type{Bool}, inds::AbstractUnitRange, r::Range)
210212
@_propagate_inbounds_meta
211213
isempty(r) | (checkindex(Bool, inds, first(r)) & checkindex(Bool, inds, last(r)))
212214
end
213-
checkindex{N}(::Type{Bool}, indx::UnitRange, I::AbstractArray{Bool,N}) = N == 1 && indx == indices1(I)
214-
function checkindex(::Type{Bool}, inds::UnitRange, I::AbstractArray)
215+
checkindex{N}(::Type{Bool}, indx::AbstractUnitRange, I::AbstractArray{Bool,N}) = N == 1 && indx == indices1(I)
216+
function checkindex(::Type{Bool}, inds::AbstractUnitRange, I::AbstractArray)
215217
@_inline_meta
216218
b = true
217219
for i in I
@@ -312,7 +314,6 @@ checkbounds(A::AbstractArray) = checkbounds(A, 1) # 0-d case
312314
## Constructors ##
313315

314316
# default arguments to similar()
315-
typealias SimIdx Union{Integer,UnitRangeInteger}
316317
"""
317318
similar(array, [element_type=eltype(array)], [dims=size(array)])
318319
@@ -351,17 +352,15 @@ different element type it will create a regular `Array` instead:
351352
See also `allocate_for`.
352353
"""
353354
similar{T}(a::AbstractArray{T}) = similar(a, T)
354-
similar( a::AbstractArray, T::Type) = _similar(indicesbehavior(a), a, T)
355+
similar( a::AbstractArray, T::Type) = similar(a, T, indices(a))
355356
similar{T}(a::AbstractArray{T}, dims::Tuple) = similar(a, T, dims)
356-
similar{T}(a::AbstractArray{T}, dims::SimIdx...) = similar(a, T, dims)
357-
similar( a::AbstractArray, T::Type, dims::SimIdx...) = similar(a, T, dims)
358-
similar( a::AbstractArray, T::Type, dims::DimsInteger) = similar(a, T, convert(Dims, dims))
357+
similar{T}(a::AbstractArray{T}, dims::DimOrInd...) = similar(a, T, dims)
358+
similar( a::AbstractArray, T::Type, dims::DimOrInd...) = similar(a, T, dims)
359+
similar( a::AbstractArray, T::Type, dims::DimsInteger) = similar(a, T, Dims(dims))
359360
# similar creates an Array by default
361+
similar( a::AbstractArray, T::Type, inds::IndicesOne) = similar(a, T, map(last, inds))
360362
similar( a::AbstractArray, T::Type, dims::Dims) = Array(T, dims)
361363

362-
_similar(::IndicesStartAt1, a::AbstractArray, T::Type) = similar(a, T, size(a))
363-
_similar(::IndicesBehavior, a::AbstractArray, T::Type) = similar(a, T, indices(a))
364-
365364
"""
366365
allocate_for(storagetype, referencearray, [shape])
367366
@@ -1300,10 +1299,11 @@ function _sub2ind(inds, L, ind, i::Integer, I::Integer...)
13001299
end
13011300

13021301
nextL(L, l::Integer) = L*l
1303-
nextL(L, r::UnitRange) = L*unsafe_length(r)
1302+
nextL(L, r::AbstractUnitRange) = L*unsafe_length(r)
13041303
offsetin(i, l::Integer) = i-1
1305-
offsetin(i, r::UnitRange) = i-first(r)
1304+
offsetin(i, r::AbstractUnitRange) = i-first(r)
13061305
unsafe_length(r::UnitRange) = r.stop-r.start+1
1306+
unsafe_length(r::OneTo) = length(r)
13071307

13081308
ind2sub(::Tuple{}, ind::Integer) = (@_inline_meta; ind == 1 ? () : throw(BoundsError()))
13091309
ind2sub(dims::DimsInteger, ind::Integer) = (@_inline_meta; _ind2sub((), dims, ind-1))
@@ -1323,9 +1323,9 @@ function _ind2sub(out, inds, ind)
13231323
end
13241324

13251325
_lookup(ind, d::Integer) = ind+1
1326-
_lookup(ind, r::UnitRange) = ind+first(r)
1326+
_lookup(ind, r::AbstractUnitRange) = ind+first(r)
13271327
_div(ind, d::Integer) = div(ind, d), 1, d
1328-
_div(ind, r::UnitRange) = (d = unsafe_length(r); (div(ind, d), first(r), d))
1328+
_div(ind, r::AbstractUnitRange) = (d = unsafe_length(r); (div(ind, d), first(r), d))
13291329

13301330
smart_ind2sub(shape::NTuple{1}, ind) = (ind,)
13311331
smart_ind2sub(shape, ind) = ind2sub(shape, ind)

base/multidimensional.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ end
7878
CartesianRange{N}(index::CartesianIndex{N}) = CartesianRange(one(index), index)
7979
CartesianRange(::Tuple{}) = CartesianRange{CartesianIndex{0}}(CartesianIndex{0}(()),CartesianIndex{0}(()))
8080
CartesianRange{N}(sz::NTuple{N,Int}) = CartesianRange(CartesianIndex(sz))
81-
CartesianRange{N}(rngs::NTuple{N,Union{Int,UnitRange{Int}}}) = CartesianRange(CartesianIndex(map(r->first(r), rngs)), CartesianIndex(map(r->last(r), rngs)))
81+
CartesianRange{N}(rngs::NTuple{N,Union{Integer,AbstractUnitRange}}) = CartesianRange(CartesianIndex(map(r->first(r), rngs)), CartesianIndex(map(r->last(r), rngs)))
8282

8383
ndims(R::CartesianRange) = length(R.start)
8484
ndims{I<:CartesianIndex}(::Type{CartesianRange{I}}) = length(I)

0 commit comments

Comments
 (0)