Skip to content

Commit

Permalink
Fix Int#downto and Int#upto when to is at limit of range (#6678)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmarcais authored and RX14 committed Sep 10, 2018
1 parent d8a1601 commit f233f53
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 16 deletions.
74 changes: 74 additions & 0 deletions spec/std/int_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,17 @@ describe "Int" do
sum.should eq(6)
end

it "does upto max" do
i = sum = 0
(Int32::MAX - 3).upto(Int32::MAX) do |n|
i += 1
sum += Int32::MAX - n
n.should be >= (Int32::MAX - 3)
end.should be_nil
i.should eq(4)
sum.should eq(6)
end

it "gets upto iterator" do
iter = 1.upto(3)
iter.next.should eq(1)
Expand All @@ -465,6 +476,26 @@ describe "Int" do
iter.next.should eq(1)
end

it "gets upto iterator max" do
iter = (Int32::MAX - 3).upto(Int32::MAX)
iter.next.should eq(Int32::MAX - 3)
iter.next.should eq(Int32::MAX - 2)
iter.next.should eq(Int32::MAX - 1)
iter.next.should eq(Int32::MAX)
iter.next.should be_a(Iterator::Stop)

iter.rewind
iter.next.should eq(Int32::MAX - 3)
end

it "upto iterator ups and downs" do
0.upto(3).to_a.should eq([0, 1, 2, 3])
3.upto(0).to_a.should eq([] of Int32)
res = [Int32::MAX - 3, Int32::MAX - 2, Int32::MAX - 1, Int32::MAX]
(Int32::MAX - 3).upto(Int32::MAX).to_a.should eq(res)
Int32::MAX.upto(0).to_a.should eq([] of Int32)
end

it "does downto" do
i = sum = 0
3.downto(1) do |n|
Expand All @@ -475,6 +506,28 @@ describe "Int" do
sum.should eq(6)
end

it "does downto min" do
i = sum = 0
(Int32::MIN + 3).downto(Int32::MIN) do |n|
i += 1
sum += n - Int32::MIN
n.should be <= Int32::MIN + 3
end
i.should eq(4)
sum.should eq(6)
end

it "does downto min unsigned" do
i = sum = 0
3_u16.downto(0) do |n|
i += 1
sum += n
n.should be <= 3_u16
end
i.should eq(4)
sum.should eq(6)
end

it "gets downto iterator" do
iter = 3.downto(1)
iter.next.should eq(3)
Expand All @@ -486,6 +539,27 @@ describe "Int" do
iter.next.should eq(3)
end

it "downto iterator ups and downs" do
3.downto(0).to_a.should eq([3, 2, 1, 0])
3_u16.downto(0).to_a.should eq([3_u16, 2_u16, 1_u16, 0_u16])
3.downto(4).to_a.should eq([] of Int32)
3_u16.downto(4_u16).to_a.should eq([] of UInt16)
res = [Int32::MIN + 3, Int32::MIN + 2, Int32::MIN + 1, Int32::MIN]
(Int32::MIN + 3).downto(Int32::MIN).to_a.should eq(res)
end

it "gets downto iterator unsigned" do
iter = 3_u16.downto(0)
iter.next.should eq(3)
iter.next.should eq(2)
iter.next.should eq(1)
iter.next.should eq(0)
iter.next.should be_a(Iterator::Stop)

iter.rewind
iter.next.should eq(3)
end

it "gets to iterator" do
iter = 1.to(3)
iter.next.should eq(1)
Expand Down
38 changes: 22 additions & 16 deletions src/int.cr
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,11 @@ struct Int
end

def upto(to, &block : self ->) : Nil
return unless self <= to
x = self
while x <= to
while true
yield x
return if x == to
x += 1
end
end
Expand All @@ -365,9 +367,11 @@ struct Int
end

def downto(to, &block : self ->) : Nil
return unless self >= to
x = self
while x >= to
while true
yield x
return if x == to
x -= 1
end
end
Expand Down Expand Up @@ -539,23 +543,24 @@ struct Int
@from : T
@to : N
@current : T
@done : Bool

def initialize(@from : T, @to : N)
@current = @from
@done = !(@from <= @to)
end

def next
if @current > @to
stop
else
value = @current
@current += 1
value
end
return stop if @done
value = @current
@done = @current == @to
@current += 1 unless @done
value
end

def rewind
@current = @from
@done = !(@from <= @to)
self
end
end
Expand All @@ -566,23 +571,24 @@ struct Int
@from : T
@to : N
@current : T
@done : Bool

def initialize(@from : T, @to : N)
@current = @from
@done = !(@from >= @to)
end

def next
if @current < @to
stop
else
value = @current
@current -= 1
value
end
return stop if @done
value = @current
@done = @current == @to
@current -= 1 unless @done
value
end

def rewind
@current = @from
@done = !(@from >= @to)
self
end
end
Expand Down

0 comments on commit f233f53

Please sign in to comment.