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