From a9770bac6375c9d4ff8ba8bb1842841aec7c59e3 Mon Sep 17 00:00:00 2001 From: marcandre Date: Sun, 10 Dec 2017 22:36:28 +0000 Subject: Add case equality arity to Enumerable#all?, any?, none? and one?, and specialized Array#any? and Hash#any? Based on patch by D.E. Akers [#11286] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61098 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- hash.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'hash.c') diff --git a/hash.c b/hash.c index cd1cc1437f..627f207d8e 100644 --- a/hash.c +++ b/hash.c @@ -2983,6 +2983,17 @@ any_p_i_fast(VALUE key, VALUE value, VALUE arg) return ST_CONTINUE; } +static int +any_p_i_pattern(VALUE key, VALUE value, VALUE arg) +{ + VALUE ret = rb_funcall(((VALUE *)arg)[1], idEqq, 1, rb_assoc_new(key, value)); + if (RTEST(ret)) { + *(VALUE *)arg = Qtrue; + return ST_STOP; + } + return ST_CONTINUE; +} + /* * call-seq: * hsh.any? [{ |(key, value)| block }] -> true or false @@ -2991,20 +3002,29 @@ any_p_i_fast(VALUE key, VALUE value, VALUE arg) */ static VALUE -rb_hash_any_p(VALUE hash) +rb_hash_any_p(int argc, VALUE *argv, VALUE hash) { - VALUE ret = Qfalse; + VALUE args[2]; + args[0] = Qfalse; + rb_check_arity(argc, 0, 1); if (RHASH_EMPTY_P(hash)) return Qfalse; - if (!rb_block_given_p()) { - /* yields pairs, never false */ - return Qtrue; + if (argc) { + args[1] = argv[0]; + + rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args); } - if (rb_block_arity() > 1) - rb_hash_foreach(hash, any_p_i_fast, (VALUE)&ret); - else - rb_hash_foreach(hash, any_p_i, (VALUE)&ret); - return ret; + else { + if (!rb_block_given_p()) { + /* yields pairs, never false */ + return Qtrue; + } + if (rb_block_arity() > 1) + rb_hash_foreach(hash, any_p_i_fast, (VALUE)args); + else + rb_hash_foreach(hash, any_p_i, (VALUE)args); + } + return args[0]; } /* @@ -4663,7 +4683,7 @@ Init_Hash(void) rb_define_method(rb_cHash, "compare_by_identity", rb_hash_compare_by_id, 0); rb_define_method(rb_cHash, "compare_by_identity?", rb_hash_compare_by_id_p, 0); - rb_define_method(rb_cHash, "any?", rb_hash_any_p, 0); + rb_define_method(rb_cHash, "any?", rb_hash_any_p, -1); rb_define_method(rb_cHash, "dig", rb_hash_dig, -1); rb_define_method(rb_cHash, "<=", rb_hash_le, 1); -- cgit v1.2.3