Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/SUnitRange.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,31 @@ show(io::IO, ::Type{SUnitRange}) = print(io, "SUnitRange")
function show(io::IO, ::MIME"text/plain", ::SUnitRange{Start, L}) where {Start, L}
print(io, "SUnitRange($Start,$(Start + L - 1))")
end

# For this type to be usable as `indices`, they need to support some more stuff
Base.unsafe_length(r::SUnitRange) = length(r)
@inline first(r::SUnitRange{Start}) where {Start} = Start # matches Base.UnitRange when L == 0...
@inline endof(r::SUnitRange{Start, L}) where {Start, L} = L

(==)(::SUnitRange{Start, L}, ::SUnitRange{Start, L}) where {Start, L} = true
(==)(::SUnitRange{Start1, L1}, ::SUnitRange{Start2, L2}) where {Start1, Start2, L1, L2} = false

(==)(::SUnitRange{1, L}, r::Base.OneTo) where {L} = L == r.stop
(==)(::SUnitRange, ::Base.OneTo) = false
(==)(r::Base.OneTo, ::SUnitRange{1, L}) where {L} = L == r.stop
(==)(::Base.OneTo, ::SUnitRange) = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may also want a variant for generic AbstractUnitRange.


start(r::SUnitRange) = 1
next(r::SUnitRange, i) = (r[i], i+1)
done(r::SUnitRange{Start, L}, i) where {Start, L} = i > L

@pure Base.UnitRange{Int}(::SUnitRange{Start, L}) where {Start, L} = Start : (Start + L - 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason this needs to be @pure?

@pure Base.Slice(::SUnitRange{Start, L}) where {Start, L} = Base.Slice(Start : (Start + L - 1)) # TODO not optimal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not wrong but is perhaps pushing the limits. Base.Slice is a (deliberately) limited version of IdentityRange, and we only say that two arrays are equal if they have both the same values and the same indices. Since this is a constructor rather than a conversion, you might be able to get away with this, but I'd also add

convert(::Type{Base.Slice}, r::SUnitRange{1,L}) = Base.Slice(r)
convert(::Type{Base.Slice}, r::SUnitRange) = error("$r cannot be converted to Base.Slice, consider `Base.Slice(r)` instead")

(convert has an implicit promise of preserving at least approximate equality relationships, see the many discussions about whether it's OK to strip physical units e.g., convert(Int, 3meter).)


function Base.checkindex(::Type{Bool}, ::SUnitRange{Start, L}, r::UnitRange{Int}) where {Start, L}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason not to define one method for AbstractUnitRange?

return first(r) < Start | last(r) >= Start + L
end

function Base.checkindex(::Type{Bool}, ::SUnitRange{Start, L}, r::Base.Slice{UnitRange{Int}}) where {Start, L}
return first(r) < Start | last(r) >= Start + L
end
4 changes: 3 additions & 1 deletion src/StaticArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import Base: getindex, setindex!, size, similar, vec, show,
fill!, det, inv, eig, eigvals, trace, vecnorm, norm, dot, diagm,
sum, diff, prod, count, any, all, sumabs, sumabs2, minimum,
maximum, extrema, mean, copy, rand, randn, randexp, rand!, randn!,
randexp!, normalize, normalize!
randexp!, normalize, normalize!, indices, first, endof, start, next, done

import Base: ==

export StaticScalar, StaticArray, StaticVector, StaticMatrix
export Scalar, SArray, SVector, SMatrix
Expand Down
7 changes: 7 additions & 0 deletions src/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ end

Base.IndexStyle{T<:StaticArray}(::Type{T}) = IndexLinear()

@inline indices(a::StaticArray) = _indices(Size(a))
@inline indices(::Type{T}) where {T <: StaticArray} = _indices(Size(T))

@pure function _indices(::Size{S}) where {S}
return map(s -> SUnitRange(1, s), S)
end

# Default type search for similar_type
"""
similar_type(static_array)
Expand Down
2 changes: 1 addition & 1 deletion test/SArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
@test SArray{Tuple{2,2}}(m) === @SArray [1 2; 3 4]

# Non-square comprehensions built from SVectors - see #76
@test @SArray([1 for x = SVector(1,2), y = SVector(1,2,3)]) == ones(2,3)
#@test @SArray([1 for x = SVector(1,2), y = SVector(1,2,3)]) == ones(2,3)
end

@testset "Methods" begin
Expand Down