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:
parent
cc27cd26d7
commit
9c5804ac1c
Notes:
git
2020-06-29 11:06:52 +09:00
1 changed files with 36 additions and 20 deletions
56
range.c
56
range.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue