[前][次][番号順一覧][スレッド一覧][生データ]

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

[前][次][番号順一覧][スレッド一覧][生データ]