diff options
author | marcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-06 17:15:45 +0000 |
---|---|---|
committer | marcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-06 17:15:45 +0000 |
commit | 44374034268913246d517ff25365e0bccb453e02 (patch) | |
tree | 99b402caebc8f0d2251de279bdfdfe8b5f96a863 /string.c | |
parent | 3a4eb4dd39b4a6687068de391c8543008c3f977c (diff) | |
download | ruby-44374034268913246d517ff25365e0bccb453e02.tar.gz |
* string.c: Support for String#{each_byte,each_char,each_codepoint}.size
[Feature #6636]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37520 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 25 |
1 files changed, 22 insertions, 3 deletions
@@ -6222,6 +6222,11 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str) return orig; } +static VALUE +rb_str_each_byte_size(VALUE str, VALUE args) +{ + return LONG2FIX(RSTRING_LEN(str)); +} /* * call-seq: @@ -6246,13 +6251,27 @@ rb_str_each_byte(VALUE str) { long i; - RETURN_ENUMERATOR(str, 0, 0); + RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_byte_size); for (i=0; i<RSTRING_LEN(str); i++) { rb_yield(INT2FIX(RSTRING_PTR(str)[i] & 0xff)); } return str; } +static VALUE +rb_str_each_char_size(VALUE str) +{ + long len = RSTRING_LEN(str); + if (!single_byte_optimizable(str)) { + const char *ptr = RSTRING_PTR(str); + rb_encoding *enc = rb_enc_get(str); + const char *end_ptr = ptr + len; + for (len = 0; ptr < end_ptr; ++len) { + ptr += rb_enc_mbclen(ptr, end_ptr, enc); + } + } + return LONG2FIX(len); +} /* * call-seq: @@ -6280,7 +6299,7 @@ rb_str_each_char(VALUE str) const char *ptr; rb_encoding *enc; - RETURN_ENUMERATOR(str, 0, 0); + RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_char_size); str = rb_str_new4(str); ptr = RSTRING_PTR(str); len = RSTRING_LEN(str); @@ -6333,7 +6352,7 @@ rb_str_each_codepoint(VALUE str) rb_encoding *enc; if (single_byte_optimizable(str)) return rb_str_each_byte(str); - RETURN_ENUMERATOR(str, 0, 0); + RETURN_SIZED_ENUMERATOR(str, 0, 0, rb_str_each_char_size); str = rb_str_new4(str); ptr = RSTRING_PTR(str); end = RSTRING_END(str); |