summaryrefslogtreecommitdiff
path: root/range.c
diff options
context:
space:
mode:
authorKouhei Yanagita <[email protected]>2024-12-10 11:51:49 +0900
committerNobuyoshi Nakada <[email protected]>2024-12-10 23:12:27 +0900
commit3422bfcab6bfdedd10e5c85f5fd6334387712bc6 (patch)
tree683ecdc8a957e1dbf1c405b59ec4726c996a3c04 /range.c
parentd5abcae43500e3b51b9fcb0918d7e849e024aee1 (diff)
[Bug #20936] Fix #size for Range#reverse_each
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/12301
Diffstat (limited to 'range.c')
-rw-r--r--range.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/range.c b/range.c
index 7ddb9908f6..e6c2897083 100644
--- a/range.c
+++ b/range.c
@@ -908,6 +908,10 @@ sym_each_i(VALUE v, VALUE arg)
return each_i(rb_str_intern(v), arg);
}
+#define CANT_ITERATE_FROM(x) \
+ rb_raise(rb_eTypeError, "can't iterate from %s", \
+ rb_obj_classname(x))
+
/*
* call-seq:
* size -> non_negative_integer or Infinity or nil
@@ -944,13 +948,48 @@ range_size(VALUE range)
}
if (!discrete_object_p(b)) {
- rb_raise(rb_eTypeError, "can't iterate from %s",
- rb_obj_classname(b));
+ CANT_ITERATE_FROM(b);
}
return Qnil;
}
+static VALUE
+range_reverse_size(VALUE range)
+{
+ VALUE b = RANGE_BEG(range), e = RANGE_END(range);
+
+ if (NIL_P(e)) {
+ CANT_ITERATE_FROM(e);
+ }
+
+ if (RB_INTEGER_TYPE_P(b)) {
+ if (rb_obj_is_kind_of(e, rb_cNumeric)) {
+ return ruby_num_interval_step_size(b, e, INT2FIX(1), EXCL(range));
+ }
+ else {
+ CANT_ITERATE_FROM(e);
+ }
+ }
+
+ if (NIL_P(b)) {
+ if (RB_INTEGER_TYPE_P(e)) {
+ return DBL2NUM(HUGE_VAL);
+ }
+ else {
+ CANT_ITERATE_FROM(e);
+ }
+ }
+
+ if (!discrete_object_p(b)) {
+ CANT_ITERATE_FROM(e);
+ }
+
+ return Qnil;
+}
+
+#undef CANT_ITERATE_FROM
+
/*
* call-seq:
* to_a -> array
@@ -979,6 +1018,12 @@ range_enum_size(VALUE range, VALUE args, VALUE eobj)
return range_size(range);
}
+static VALUE
+range_enum_reverse_size(VALUE range, VALUE args, VALUE eobj)
+{
+ return range_reverse_size(range);
+}
+
RBIMPL_ATTR_NORETURN()
static void
range_each_bignum_endless(VALUE beg)
@@ -1225,7 +1270,7 @@ range_reverse_each_negative_bignum_section(VALUE beg, VALUE end)
static VALUE
range_reverse_each(VALUE range)
{
- RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);
+ RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_reverse_size);
VALUE beg = RANGE_BEG(range);
VALUE end = RANGE_END(range);