From 7f95eed19e22cb9a4867819355fe4ab99f85fd16 Mon Sep 17 00:00:00 2001 From: mame Date: Thu, 19 Apr 2018 15:18:50 +0000 Subject: Introduce endless range [Feature#12912] Typical usages: ``` p ary[1..] # drop the first element; identical to ary[1..-1] (1..).each {|n|...} # iterate forever from 1; identical to 1.step{...} ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63192 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- string.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'string.c') diff --git a/string.c b/string.c index 29457c0fb3..ad9ba6f355 100644 --- a/string.c +++ b/string.c @@ -4325,6 +4325,50 @@ str_upto_each(VALUE beg, VALUE end, int excl, int (*each)(VALUE, VALUE), VALUE a return beg; } +VALUE +rb_str_upto_endless_each(VALUE beg, VALUE (*each)(VALUE, VALUE), VALUE arg) +{ + VALUE current; + ID succ; + + CONST_ID(succ, "succ"); + /* both edges are all digits */ + if (is_ascii_string(beg) && ISDIGIT(RSTRING_PTR(beg)[0]) && + all_digits_p(RSTRING_PTR(beg), RSTRING_LEN(beg))) { + VALUE b, args[2], fmt = rb_fstring_cstr("%.*d"); + int width = RSTRING_LENINT(beg); + b = rb_str_to_inum(beg, 10, FALSE); + if (FIXNUM_P(b)) { + long bi = FIX2LONG(b); + rb_encoding *usascii = rb_usascii_encoding(); + + while (FIXABLE(bi)) { + (*each)(rb_enc_sprintf(usascii, "%.*ld", width, bi), arg); + bi++; + } + b = LONG2NUM(bi); + } + args[0] = INT2FIX(width); + while (1) { + args[1] = b; + (*each)(rb_str_format(numberof(args), args, fmt), arg); + b = rb_funcallv(b, succ, 0, 0); + } + } + /* normal case */ + current = rb_str_dup(beg); + while (1) { + VALUE next = rb_funcallv(current, succ, 0, 0); + (*each)(current, arg); + current = next; + StringValue(current); + if (RSTRING_LEN(current) == 0) + break; + } + + return beg; +} + static int include_range_i(VALUE str, VALUE arg) { -- cgit v1.2.3