yarv-diff:218
From: ko1 atdot.net
Date: 9 Feb 2006 17:19:49 -0000
Subject: [yarv-diff:218] r376 - trunk
Author: matz
Date: 2006-02-10 02:19:49 +0900 (Fri, 10 Feb 2006)
New Revision: 376
Modified:
trunk/bignum.c
trunk/enum.c
Log:
merge 1.9 modifies.
Modified: trunk/bignum.c
===================================================================
--- trunk/bignum.c 2006-02-09 17:09:35 UTC (rev 375)
+++ trunk/bignum.c 2006-02-09 17:19:49 UTC (rev 376)
@@ -2,8 +2,8 @@
bignum.c -
- $Author: ocean $
- $Date: 2005/10/21 06:25:17 $
+ $Author: akr $
+ $Date: 2005/12/16 18:59:01 $
created at: Fri Jun 10 00:48:55 JST 1994
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -1793,6 +1793,7 @@
VALUE z;
BDIGIT_DBL num = 0;
long i, j;
+ volatile VALUE save_x;
if (shift < 0) return rb_big_lshift(x, INT2FIX(-shift));
@@ -1803,7 +1804,7 @@
return INT2FIX(-1);
}
if (!RBIGNUM(x)->sign) {
- x = rb_big_clone(x);
+ save_x = x = rb_big_clone(x);
get2comp(x);
}
xds = BDIGITS(x);
Modified: trunk/enum.c
===================================================================
--- trunk/enum.c 2006-02-09 17:09:35 UTC (rev 375)
+++ trunk/enum.c 2006-02-09 17:19:49 UTC (rev 376)
@@ -2,8 +2,8 @@
enum.c -
- $Author: nobu $
- $Date: 2005/10/11 12:30:47 $
+ $Author: matz $
+ $Date: 2006/02/05 15:26:52 $
created at: Fri Oct 1 15:15:19 JST 1993
Copyright (C) 1993-2003 Yukihiro Matsumoto
@@ -172,6 +172,45 @@
}
static VALUE
+find_index_i(VALUE i, VALUE *memo)
+{
+ if (RTEST(rb_yield(i))) {
+ memo[0] = UINT2NUM(memo[1]);
+ rb_iter_break();
+ }
+ memo[1]++;
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.find_index(ifnone = nil) {| obj | block } => int
+ *
+ * Passes each entry in <i>enum</i> to <em>block</em>. Returns the
+ * index for the first for which <em>block</em> is not <code>false</code>.
+ * If no object matches, returns <code>nil</code>
+ *
+ * (1..10).find_index {|i| i % 5 == 0 and i % 7 == 0 } #=> nil
+ * (1..100).find_index {|i| i % 5 == 0 and i % 7 == 0 } #=> 35
+ *
+ */
+
+static VALUE
+enum_find_index(VALUE obj)
+{
+ VALUE memo[2];
+
+ RETURN_ENUMERATOR(obj, 0, 0);
+ memo[0] = Qundef;
+ memo[1] = 0;
+ rb_iterate(rb_each, obj, find_index_i, (VALUE)memo);
+ if (memo[0] != Qundef) {
+ return memo[0];
+ }
+ return Qnil;
+}
+
+static VALUE
find_all_i(VALUE i, VALUE ary)
{
if (RTEST(rb_yield(i))) {
@@ -394,8 +433,100 @@
return rb_assoc_new(ary[0], ary[1]);
}
+static VALUE
+group_by_i(VALUE i, VALUE hash)
+{
+ VALUE group = rb_yield(i);
+ VALUE values;
+
+ values = rb_hash_aref(hash, group);
+ if (NIL_P(values)) {
+ values = rb_ary_new3(1, i);
+ rb_hash_aset(hash, group, values);
+ }
+ else {
+ rb_ary_push(values, i);
+ }
+ return Qnil;
+}
+
/*
* call-seq:
+ * enum.group_by {| obj | block } => a_hash
+ *
+ * Returns a hash, which keys are evaluated result from the
+ * block, and values are arrays of elements in <i>enum</i>
+ * corresponding to the key.
+ *
+ * (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
+ *
+ */
+
+static VALUE
+enum_group_by(VALUE obj)
+{
+ VALUE hash;
+
+ RETURN_ENUMERATOR(obj, 0, 0);
+
+ hash = rb_hash_new();
+ rb_iterate(rb_each, obj, group_by_i, hash);
+
+ return hash;
+}
+
+static VALUE
+first_i(VALUE i, VALUE *ary)
+{
+ if (NIL_P(ary[0])) {
+ ary[1] = i;
+ rb_iter_break();
+ }
+ else {
+ long n = NUM2LONG(ary[0]);
+
+ if (n <= 0) {
+ rb_iter_break();
+ }
+ rb_ary_push(ary[1], i);
+ n--;
+ ary[0] = INT2NUM(n);
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.first -> obj or nil
+ * enum.first(n) -> an_array
+ *
+ * Returns the first element, or the first +n+ elements, of the enumerable.
+ * If the enumerable is empty, the first form returns <code>nil</code>, and the
+ * second form returns an empty array.
+ *
+ */
+
+static VALUE
+enum_first(int argc, VALUE *argv, VALUE obj)
+{
+ VALUE n, ary[2];
+
+ rb_scan_args(argc, argv, "01", &n);
+
+ if (NIL_P(n)) {
+ ary[0] = ary[1] = Qnil;
+ }
+ else {
+ ary[0] = n;
+ ary[1] = rb_ary_new2(NUM2LONG(n));
+ }
+ rb_iterate(rb_each, obj, first_i, (VALUE)ary);
+
+ return ary[1];
+}
+
+/*
+ * call-seq:
* enum.sort => array
* enum.sort {| a, b | block } => array
*
@@ -449,7 +580,7 @@
* values in <i>enum</i> through the given block.
*
* %w{ apple pear fig }.sort_by {|word| word.length}
- #=> ["fig", "pear", "apple"]
+ #=> ["fig", "pear", "apple"]
*
* The current implementation of <code>sort_by</code> generates an
* array of tuples containing the original collection element and the
@@ -570,9 +701,9 @@
* <code>all?</code> will return <code>true</code> only if none of the
* collection members are <code>false</code> or <code>nil</code>.)
*
- * %w{ ant bear cat}.all? {|word| word.length >= 3} #=> true
- * %w{ ant bear cat}.all? {|word| word.length >= 4} #=> false
- * [ nil, true, 99 ].all? #=> false
+ * %w{ant bear cat}.all? {|word| word.length >= 3} #=> true
+ * %w{ant bear cat}.all? {|word| word.length >= 4} #=> false
+ * [ nil, true, 99 ].all? #=> false
*
*/
@@ -617,9 +748,9 @@
* of the collection members is not <code>false</code> or
* <code>nil</code>.
*
- * %w{ ant bear cat}.any? {|word| word.length >= 3} #=> true
- * %w{ ant bear cat}.any? {|word| word.length >= 4} #=> true
- * [ nil, true, 99 ].any? #=> true
+ * %w{ant bear cat}.any? {|word| word.length >= 3} #=> true
+ * %w{ant bear cat}.any? {|word| word.length >= 4} #=> true
+ * [ nil, true, 99 ].any? #=> true
*
*/
@@ -633,6 +764,104 @@
}
static VALUE
+one_iter_i(VALUE i, VALUE *memo)
+{
+ if (RTEST(rb_yield(i))) {
+ if (*memo == Qundef) {
+ *memo = Qtrue;
+ }
+ else if (*memo == Qtrue) {
+ *memo = Qfalse;
+ }
+ }
+ return Qnil;
+}
+
+static VALUE
+one_i(VALUE i, VALUE *memo)
+{
+ if (RTEST(i)) {
+ if (*memo == Qundef) {
+ *memo = Qtrue;
+ }
+ else if (*memo == Qtrue) {
+ *memo = Qfalse;
+ }
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.one? [{|obj| block }] => true or false
+ *
+ * Passes each element of the collection to the given block. The method
+ * returns <code>true</code> if the block returns <code>true</code>
+ * exactly once. If the block is not given, <code>one?</code> will return
+ * <code>true</code> only if exactly one of the collection members are
+ * true.
+ *
+ * %w{ant bear cat}.one? {|word| word.length == 4} #=> true
+ * %w{ant bear cat}.one? {|word| word.length >= 4} #=> false
+ * [ nil, true, 99 ].one? #=> true
+ *
+ */
+
+static VALUE
+enum_one(VALUE obj)
+{
+ VALUE result = Qundef;
+
+ rb_iterate(rb_each, obj, rb_block_given_p() ? one_iter_i : one_i, (VALUE)&result);
+ if (result == Qundef) return Qfalse;
+ return result;
+}
+
+static VALUE
+none_iter_i(VALUE i, VALUE *memo)
+{
+ if (RTEST(rb_yield(i))) {
+ *memo = Qfalse;
+ rb_iter_break();
+ }
+ return Qnil;
+}
+
+static VALUE
+none_i(VALUE i, VALUE *memo)
+{
+ if (RTEST(i)) {
+ *memo = Qfalse;
+ rb_iter_break();
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * enum.none? [{|obj| block }] => true or false
+ *
+ * Passes each element of the collection to the given block. The method
+ * returns <code>true</code> if the block never returns <code>true</code>
+ * for all elements. If the block is not given, <code>one?</code> will return
+ * <code>true</code> only if any of the collection members is true.
+ *
+ * %w{ant bear cat}.one? {|word| word.length == 4} #=> true
+ * %w{ant bear cat}.one? {|word| word.length >= 4} #=> false
+ * [ nil, true, 99 ].one? #=> true
+ *
+ */
+
+static VALUE
+enum_none(VALUE obj)
+{
+ VALUE result = Qtrue;
+
+ rb_iterate(rb_each, obj, rb_block_given_p() ? none_iter_i : none_i, (VALUE)&result);
+ return result;
+}
+
+static VALUE
min_i(VALUE i, VALUE *memo)
{
VALUE cmp;
@@ -989,6 +1218,7 @@
rb_define_method(rb_mEnumerable,"count", enum_count, -1);
rb_define_method(rb_mEnumerable,"find", enum_find, -1);
rb_define_method(rb_mEnumerable,"detect", enum_find, -1);
+ rb_define_method(rb_mEnumerable,"find_index", enum_find_index, 0);
rb_define_method(rb_mEnumerable,"find_all", enum_find_all, 0);
rb_define_method(rb_mEnumerable,"select", enum_find_all, 0);
rb_define_method(rb_mEnumerable,"reject", enum_reject, 0);
@@ -996,8 +1226,12 @@
rb_define_method(rb_mEnumerable,"map", enum_collect, 0);
rb_define_method(rb_mEnumerable,"inject", enum_inject, -1);
rb_define_method(rb_mEnumerable,"partition", enum_partition, 0);
+ rb_define_method(rb_mEnumerable,"group_by", enum_group_by, 0);
+ rb_define_method(rb_mEnumerable,"first", enum_first, -1);
rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
+ rb_define_method(rb_mEnumerable,"one?", enum_one, 0);
+ rb_define_method(rb_mEnumerable,"none?", enum_none, 0);
rb_define_method(rb_mEnumerable,"min", enum_min, 0);
rb_define_method(rb_mEnumerable,"max", enum_max, 0);
rb_define_method(rb_mEnumerable,"min_by", enum_min_by, 0);
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml