Skip to content

Commit

Permalink
add cendof, cget, cset! functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Oct 10, 2014
1 parent 4dc1679 commit 1d929d7
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
5 changes: 5 additions & 0 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ndims{T,n}(::Type{AbstractArray{T,n}}) = n
ndims{T<:AbstractArray}(::Type{T}) = ndims(super(T))
length(t::AbstractArray) = prod(size(t))::Int
endof(a::AbstractArray) = length(a)
cendof(a::AbstractArray) = unsigned(length(a) - 1) # precondition: !isempty(a)
first(a::AbstractArray) = a[1]
first(a) = next(a,start(a))[1]
last(a) = a[end]
Expand Down Expand Up @@ -374,6 +375,8 @@ imag{T<:Real}(x::AbstractArray{T}) = zero(x)

getindex(t::AbstractArray, i::Real) = error("indexing not defined for ", typeof(t))

cget(t::AbstractArray, i::Real) = @inbounds return t[i+1]

# linear indexing with a single multi-dimensional index
function getindex(A::AbstractArray, I::AbstractArray)
x = similar(A, size(I))
Expand Down Expand Up @@ -440,6 +443,8 @@ setindex!(t::AbstractArray, x, i::Real) =
error("setindex! not defined for ",typeof(t))
setindex!(t::AbstractArray, x) = throw(MethodError(setindex!, (t, x)))

cset!(t::AbstractArray, x, i::Real) = @inbounds return t[i+1] = x

## Indexing: handle more indices than dimensions if "extra" indices are 1

# Don't require vector/matrix subclasses to implement more than 1/2 indices,
Expand Down
3 changes: 0 additions & 3 deletions base/int.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
## integer arithmetic ##

const IntTypes = (Int8, Uint8, Int16, Uint16, Int32, Uint32,
Int64, Uint64, Int128, Uint128)

+(x::Int, y::Int) = box(Int,add_int(unbox(Int,x),unbox(Int,y)))
<(x::Int, y::Int) = slt_int(unbox(Int,x),unbox(Int,y))

Expand Down
17 changes: 17 additions & 0 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,21 @@ let smallint = (Int === Int64 ?
length{T <: smallint}(r::UnitRange{T}) = int(r.stop) - int(r.start) + 1
end

cendof(r::StepRange) = unsigned(endof(r) - 1)

const IntTypes = (Int8, Uint8, Int16, Uint16, Int32, Uint32,
Int64, Uint64, Int128, Uint128)

function cendof{T<:Union(IntTypes...),S<:Union(IntTypes...)}(r::StepRange{T,S})
if r.step > 0
div(unsigned(r.stop - r.start), r.step)
else
div(unsigned(r.start - r.stop), -r.step)
end
end

cendof{T<:Union(IntTypes...)}(r::UnitRange{T}) = unsigned(r.stop - r.start)

first{T}(r::OrdinalRange{T}) = oftype(T, r.start)
first(r::FloatRange) = r.start/r.divisor

Expand Down Expand Up @@ -263,6 +278,8 @@ function getindex{T}(r::FloatRange{T}, i::Integer)
oftype(T, (r.start + (i-1)*r.step)/r.divisor)
end

cget{T<:Union(IntTypes...)}(r::Range{T}, i::Integer) = itrunc(T, unsigned(first(r)) + unsigned(i)*unsigned(step(r)))

function check_indexingrange(s, r)
sl = length(s)
rl = length(r)
Expand Down
12 changes: 12 additions & 0 deletions test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -372,3 +372,15 @@ let smallint = (Int === Int64 ?
@test length(typemin(T):typemax(T)) == 2^(8*sizeof(T))
end
end

# cendof, cget
for r in (typemin(Int):typemax(Int), typemin(Int):1:typemax(Int))
@test Base.cendof(r) == typemax(Uint)
@test Base.cget(r, 0) == typemin(Int)
@test Base.cget(r, Base.cendof(r)) == typemax(Int)
end
let r = typemax(Int):-1:typemin(Int)
@test Base.cendof(r) == typemax(Uint)
@test Base.cget(r, 0) == typemax(Int)
@test Base.cget(r, Base.cendof(r)) == typemin(Int)
end

0 comments on commit 1d929d7

Please sign in to comment.