1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

range_each: do not goto into a branch

I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
This commit is contained in:
卜部昌平 2020-06-16 14:31:11 +09:00
parent cc27cd26d7
commit 9c5804ac1c
Notes: git 2020-06-29 11:06:52 +09:00

56
range.c
View file

@ -829,6 +829,36 @@ range_enum_size(VALUE range, VALUE args, VALUE eobj)
return range_size(range);
}
RBIMPL_ATTR_NORETURN()
static void
range_each_bignum_endless(VALUE beg)
{
for (;; beg = rb_big_plus(beg, INT2FIX(1))) {
rb_yield(beg);
}
}
RBIMPL_ATTR_NORETURN()
static void
range_each_fixnum_endless(VALUE beg)
{
for (long i = FIX2LONG(beg); FIXABLE(i); i++) {
rb_yield(LONG2FIX(i));
}
range_each_bignum_endless(LONG2NUM(RUBY_FIXNUM_MAX + 1));
}
static VALUE
range_each_fixnum_loop(VALUE beg, VALUE end, VALUE range)
{
long lim = FIX2LONG(end) + !EXCL(range);
for (long i = FIX2LONG(beg); i < lim; i++) {
rb_yield(LONG2FIX(i));
}
return range;
}
/*
* call-seq:
* rng.each {| i | block } -> rng
@ -854,7 +884,7 @@ static VALUE
range_each(VALUE range)
{
VALUE beg, end;
long i, lim;
long i;
RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);
@ -862,24 +892,10 @@ range_each(VALUE range)
end = RANGE_END(range);
if (FIXNUM_P(beg) && NIL_P(end)) {
fixnum_endless:
i = FIX2LONG(beg);
while (FIXABLE(i)) {
rb_yield(LONG2FIX(i++));
}
beg = LONG2NUM(i);
bignum_endless:
for (;; beg = rb_big_plus(beg, INT2FIX(1)))
rb_yield(beg);
range_each_fixnum_endless(beg);
}
else if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
fixnum_loop:
lim = FIX2LONG(end);
if (!EXCL(range))
lim += 1;
for (i = FIX2LONG(beg); i < lim; i++) {
rb_yield(LONG2FIX(i));
}
return range_each_fixnum_loop(beg, end, range);
}
else if (RB_INTEGER_TYPE_P(beg) && (NIL_P(end) || RB_INTEGER_TYPE_P(end))) {
if (SPECIAL_CONST_P(end) || RBIGNUM_POSITIVE_P(end)) { /* end >= FIXNUM_MIN */
@ -888,11 +904,11 @@ range_each(VALUE range)
do {
rb_yield(beg);
} while (!FIXNUM_P(beg = rb_big_plus(beg, INT2FIX(1))));
if (NIL_P(end)) goto fixnum_endless;
if (FIXNUM_P(end)) goto fixnum_loop;
if (NIL_P(end)) range_each_fixnum_endless(beg);
if (FIXNUM_P(end)) return range_each_fixnum_loop(beg, end, range);
}
else {
if (NIL_P(end)) goto bignum_endless;
if (NIL_P(end)) range_each_bignum_endless(beg);
if (FIXNUM_P(end)) return range;
}
}