From 34f5c4061c6583fe854bdf8c792a6ffc226e3986 Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 30 May 2002 06:12:29 +0000 Subject: * range.c (range_step): iteration done using "+" if elements are Numeric. Otherwise using "succ". * range.c (range_each): iteration done using "succ". If the elements does not respond to "succ", raise TypeError. As a result, all Enumerable methods, e.g. collect, require elements to respond to "succ'. * range.c (range_member): comparison done using "each", if elements are non-Numeric or no-"succ" objects. Otherwise compare using "<=>". * range.c (Init_Range): remove "size" and "length". git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2506 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- range.c | 263 ++++++++++++++++++++++++---------------------------------------- 1 file changed, 98 insertions(+), 165 deletions(-) (limited to 'range.c') diff --git a/range.c b/range.c index f8596b74d8..e621824e28 100644 --- a/range.c +++ b/range.c @@ -146,58 +146,6 @@ r_gt(a,b) return Qfalse; } -static VALUE -r_eqq_str_i(i, data) - VALUE i; - VALUE *data; -{ - if (rb_str_cmp(i, data[0]) == 0) { - data[1] = Qtrue; - rb_iter_break(); - } - return Qnil; -} - -static VALUE -range_eqq(range, obj) - VALUE range, obj; -{ - VALUE beg, end; - - beg = rb_ivar_get(range, id_beg); - end = rb_ivar_get(range, id_end); - - if (FIXNUM_P(beg) && FIXNUM_P(obj) && FIXNUM_P(end)) { - if (FIX2LONG(beg) <= FIX2LONG(obj)) { - if (EXCL(range)) { - if (FIX2LONG(obj) < FIX2LONG(end)) return Qtrue; - } - else { - if (FIX2LONG(obj) <= FIX2LONG(end)) return Qtrue; - } - } - return Qfalse; - } - else if (TYPE(beg) == T_STRING && - TYPE(obj) == T_STRING && - TYPE(end) == T_STRING) { - VALUE data[2]; - - data[0] = obj; data[1] = Qfalse; - rb_iterate(rb_each, range, r_eqq_str_i, (VALUE)data); - return data[1]; - } - else if (r_le(beg, obj)) { - if (EXCL(range)) { - if (r_lt(obj, end)) return Qtrue; - } - else { - if (r_le(obj, end)) return Qtrue; - } - } - return Qfalse; -} - static VALUE range_eql(range, obj) VALUE range, obj; @@ -216,8 +164,8 @@ range_eql(range, obj) } static VALUE -range_hash(range, obj) - VALUE range, obj; +range_hash(range) + VALUE range; { long hash = EXCL(range); VALUE v; @@ -226,19 +174,20 @@ range_hash(range, obj) hash ^= v << 1; v = rb_hash(rb_ivar_get(range, id_end)); hash ^= v << 9; + hash ^= EXCL(range) << 24; return INT2FIX(hash); } static VALUE -r_step_str(args) +str_step(args) VALUE *args; { return rb_str_upto(args[0], args[1], EXCL(args[2])); } static VALUE -r_step_str_i(i, iter) +step_i(i, iter) VALUE i; long *iter; { @@ -250,6 +199,28 @@ r_step_str_i(i, iter) return Qnil; } +static void +range_each_func(range, func, v, e, arg) + VALUE range; + void (*func) _((VALUE, void*)); + void *arg; +{ + if (EXCL(range)) { + while (r_lt(v, e)) { + if (r_eq(v, e)) break; + (*func)(v, arg); + v = rb_funcall(v, id_succ, 0, 0); + } + } + else { + while (r_le(v, e)) { + (*func)(v, arg); + if (r_eq(v, e)) break; + v = rb_funcall(v, id_succ, 0, 0); + } + } +} + static VALUE range_step(argc, argv, range) int argc; @@ -257,6 +228,7 @@ range_step(argc, argv, range) VALUE range; { VALUE b, e, step; + long unit; b = rb_ivar_get(range, id_beg); e = rb_ivar_get(range, id_end); @@ -264,27 +236,23 @@ range_step(argc, argv, range) step = INT2FIX(1); } + unit = NUM2LONG(step); + if (unit <= 0) { + rb_raise(rb_eArgError, "step can't be <= 0"); + } if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */ - long end = FIX2LONG(e), s = NUM2LONG(step); + long end = FIX2LONG(e); long i; - if (s <= 0) { - rb_raise(rb_eArgError, "step can't be <= 0"); - } + if (!EXCL(range)) end += 1; - for (i=FIX2LONG(b); i