Skip to content

Commit

Permalink
Fix #6262
Browse files Browse the repository at this point in the history
Use an Int for the accumulation variable when iterating over integer
types smaller than Int, and the type of the range when iterating over
types larger than Int
  • Loading branch information
simonster committed Mar 25, 2014
1 parent 95c9f9b commit 84b1b03
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
14 changes: 7 additions & 7 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,15 @@ colon{T<:Integer}(start::T, stop::T) =
Range1{T}(start, ifelse(stop<start, 0, int(stop-start+1)))

if Int === Int32
colon{T<:Union(Int8,Int16,Int32,Uint8,Uint16)}(start::T, stop::T) =
Range1{T}(start,
ifelse(stop < start, 0,
checked_add(checked_sub(convert(Int,stop),convert(Int,start)),1)),
0) # hack to elide negative length check
eval(:(typealias SmallInteger Union(Int8,Int16,Int32,Uint8,Uint16)))
else
colon{T<:Union(Int8,Int16,Int32,Int64,Uint8,Uint16,Uint32)}(start::T, stop::T) =
eval(:(typealias SmallInteger Union(Int8,Int16,Int32,Int64,Uint8,Uint16,Uint32)))
end
colon{T<:SmallInteger}(start::T, stop::T) =
Range1{T}(start,
ifelse(stop < start, 0,
checked_add(checked_sub(convert(Int,stop),convert(Int,start)),1)),
0) # hack to elide negative length check
end

function colon{T<:Real}(start::T, step::T, stop::T)
step != 0 || error("step cannot be zero in colon syntax")
Expand Down Expand Up @@ -238,6 +235,9 @@ done(r::Ranges, i) = (length(r) <= i)

# though these look very similar to the above, for some reason LLVM generates
# much better code for these.
start{T<:SmallInteger}(r::Range1{T}) = int(r.start)
next{T<:SmallInteger}(r::Range1{T}, i) = (oftype(T, i), i+1)
done{T<:SmallInteger}(r::Range1{T}, i) = i==r.start+r.len
start{T<:Integer}(r::Range1{T}) = r.start
next{T<:Integer}(r::Range1{T}, i) = (i, oftype(T, i+1))
done{T<:Integer}(r::Range1{T}, i) = i==oftype(T, r.start+r.len)
Expand Down
32 changes: 31 additions & 1 deletion test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,36 @@ let s = 0
@test s <= 2
end
@test s == 2

# loops covering the full range of smaller integer types
s = 0
for i = typemin(Uint8):typemax(Uint8)
s += 1
end
@test s == 256

# loops past typemax(Int)
n = 0
s = int128(0)
for i = typemax(Uint64)-2:typemax(Uint64)
n += 1
s += i
end
@test n == 3
@test s == 3*int128(typemax(Uint64)) - 3

# loops over empty ranges
s = 0
for i = 0xff:0x00
s += 1
end
@test s == 0

s = 0
for i = int128(typemax(Int128)):int128(typemin(Int128))
s += 1
end
@test s == 0
end

# sums (see #5798)
Expand All @@ -160,7 +190,7 @@ else
@test sum(int64(1:10^9-1)) == div(10^9 * (int64(10^9)-1), 2)
end

# with ranges
# operations between ranges and arrays
@test all(([1:5] + (5:-1:1)) .== 6)
@test all(((5:-1:1) + [1:5]) .== 6)
@test all(([1:5] - (1:5)) .== 0)
Expand Down

0 comments on commit 84b1b03

Please sign in to comment.