[前][次][番号順一覧][スレッド一覧]

ruby-changes:53992

From: nobu <ko1@a...>
Date: Wed, 5 Dec 2018 13:25:49 +0900 (JST)
Subject: [ruby-changes:53992] nobu:r66212 (trunk): implement Array-specific #all?, #none?, #one?

nobu	2018-12-05 13:25:44 +0900 (Wed, 05 Dec 2018)

  New Revision: 66212

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66212

  Log:
    implement Array-specific #all?, #none?, #one?
    
    Before this patch Array#all? was not implemented in Array class
    and alternatively Enumerable#all? was used, while #any? has its
    own method entry in Array class.  Similarly, Array#none? and #one?
    also lacks its own implementation.
    This patch provides Array-specific implementations for above three
    methods to enable faster method lookup.
    
    [Fix GH-2041]
    
    From: Koji Onishi <fursich0@g...>

  Modified files:
    trunk/array.c
Index: array.c
===================================================================
--- array.c	(revision 66211)
+++ array.c	(revision 66212)
@@ -6208,6 +6208,124 @@ rb_ary_any_p(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/array.c#L6208
 }
 
 /*
+ *  call-seq:
+ *     ary.all? [{|obj| block}  ]   -> true or false
+ *     ary.all?(pattern)            -> true or false
+ *
+ *  See also Enumerable#all?
+ */
+
+static VALUE
+rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
+{
+    long i, len = RARRAY_LEN(ary);
+
+    rb_check_arity(argc, 0, 1);
+    if (!len) return Qtrue;
+    if (argc) {
+        if (rb_block_given_p()) {
+            rb_warn("given block not used");
+        }
+        for (i = 0; i < RARRAY_LEN(ary); ++i) {
+            if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
+        }
+    }
+    else if (!rb_block_given_p()) {
+        for (i = 0; i < len; ++i) {
+            if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;
+        }
+    }
+    else {
+        for (i = 0; i < RARRAY_LEN(ary); ++i) {
+            if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
+        }
+    }
+    return Qtrue;
+}
+
+/*
+ *  call-seq:
+ *     ary.none? [{|obj| block}  ]   -> true or false
+ *     ary.none?(pattern)            -> true or false
+ *
+ *  See also Enumerable#none?
+ */
+
+static VALUE
+rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
+{
+    long i, len = RARRAY_LEN(ary);
+
+    rb_check_arity(argc, 0, 1);
+    if (!len) return Qtrue;
+    if (argc) {
+        if (rb_block_given_p()) {
+            rb_warn("given block not used");
+        }
+        for (i = 0; i < RARRAY_LEN(ary); ++i) {
+            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
+        }
+    }
+    else if (!rb_block_given_p()) {
+        for (i = 0; i < len; ++i) {
+            if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;
+        }
+    }
+    else {
+        for (i = 0; i < RARRAY_LEN(ary); ++i) {
+            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
+        }
+    }
+    return Qtrue;
+}
+
+/*
+ *  call-seq:
+ *     ary.one? [{|obj| block}  ]   -> true or false
+ *     ary.one?(pattern)            -> true or false
+ *
+ *  See also Enumerable#one?
+ */
+
+static VALUE
+rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
+{
+    long i, len = RARRAY_LEN(ary);
+    VALUE result = Qfalse;
+
+    rb_check_arity(argc, 0, 1);
+    if (!len) return Qfalse;
+    if (argc) {
+        if (rb_block_given_p()) {
+            rb_warn("given block not used");
+        }
+        for (i = 0; i < RARRAY_LEN(ary); ++i) {
+            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {
+                if (result) return Qfalse;
+                result = Qtrue;
+            }
+        }
+    }
+    else if (!rb_block_given_p()) {
+        for (i = 0; i < len; ++i) {
+            if (RTEST(RARRAY_AREF(ary, i))) {
+                if (result) return Qfalse;
+                result = Qtrue;
+            }
+        }
+    }
+    else {
+        for (i = 0; i < RARRAY_LEN(ary); ++i) {
+            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
+                if (result) return Qfalse;
+                result = Qtrue;
+            }
+        }
+    }
+    return result;
+}
+
+/*
  * call-seq:
  *   ary.dig(idx, ...)                 -> object
  *
@@ -6765,6 +6883,9 @@ Init_Array(void) https://github.com/ruby/ruby/blob/trunk/array.c#L6883
     rb_define_method(rb_cArray, "bsearch", rb_ary_bsearch, 0);
     rb_define_method(rb_cArray, "bsearch_index", rb_ary_bsearch_index, 0);
     rb_define_method(rb_cArray, "any?", rb_ary_any_p, -1);
+    rb_define_method(rb_cArray, "all?", rb_ary_all_p, -1);
+    rb_define_method(rb_cArray, "none?", rb_ary_none_p, -1);
+    rb_define_method(rb_cArray, "one?", rb_ary_one_p, -1);
     rb_define_method(rb_cArray, "dig", rb_ary_dig, -1);
     rb_define_method(rb_cArray, "sum", rb_ary_sum, -1);
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]