/*
* call-seq:
* enum.count => int
* enum.count(item) => int
* enum.count {| obj | block } => int
*
* Returns the number of items in <i>enum</i>, where #size is called
* if it responds to it, otherwise the items are counted through
* enumeration. If an argument is given, counts the number of items
* in <i>enum</i>, for which equals to <i>item</i>. If a block is
* given, counts the number of elements yielding a true value.
*
* ary = [1, 2, 4, 2]
* ary.count # => 4
* ary.count(2) # => 2
* ary.count{|x|x%2==0} # => 3
*
*/
static VALUE
enum_count(int argc, VALUE *argv, VALUE obj)
{
VALUE memo[2]; /* [count, condition value] */
rb_block_call_func *func;
if (argc == 0) {
if (rb_block_given_p()) {
func = count_iter_i;
}
else {
if (rb_respond_to(obj, id_size)) {
return rb_funcall(obj, id_size, 0, 0);
}
func = count_all_i;
}
}
else {
rb_scan_args(argc, argv, "1", &memo[1]);
if (rb_block_given_p()) {
rb_warn("given block not used");
}
func = count_i;
}
memo[0] = 0;
rb_block_call(obj, id_each, 0, 0, func, (VALUE)&memo);
return INT2NUM(memo[0]);
}