summaryrefslogtreecommitdiff
path: root/enumerator.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-20 08:44:08 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-20 08:44:08 +0000
commit6882b354604b8a28d7da5b457fd6ce4e1311a5be (patch)
tree596f1739e99a3e541905a89f2cbec9d24dd96591 /enumerator.c
parent42c6a5137e46b885ab28b267f85c0ddc8d49b195 (diff)
enumerator.c: Enumerator::Lazy#uniq
* enumerator.c (lazy_uniq): new method Enumerator::Lazy#uniq. [Feature #11090] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55710 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'enumerator.c')
-rw-r--r--enumerator.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/enumerator.c b/enumerator.c
index a59473a..2d692e5 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -1959,6 +1959,41 @@ lazy_drop_while(VALUE obj)
}
static VALUE
+lazy_uniq_i(VALUE i, VALUE hash, int argc, const VALUE *argv, VALUE yielder)
+{
+ if (rb_hash_add_new_element(hash, i, Qfalse))
+ return Qnil;
+ return rb_funcall2(yielder, id_yield, argc, argv);
+}
+
+static VALUE
+lazy_uniq_func(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+{
+ VALUE yielder = (--argc, *argv++);
+ i = rb_enum_values_pack(argc, argv);
+ return lazy_uniq_i(i, hash, argc, argv, yielder);
+}
+
+static VALUE
+lazy_uniq_iter(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+{
+ VALUE yielder = (--argc, *argv++);
+ i = rb_yield_values2(argc, argv);
+ return lazy_uniq_i(i, hash, argc, argv, yielder);
+}
+
+static VALUE
+lazy_uniq(VALUE obj)
+{
+ rb_block_call_func *const func =
+ rb_block_given_p() ? lazy_uniq_iter : lazy_uniq_func;
+ VALUE hash = rb_obj_hide(rb_hash_new());
+ return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
+ func, hash),
+ 0, 0);
+}
+
+static VALUE
lazy_super(int argc, VALUE *argv, VALUE lazy)
{
return enumerable_lazy(rb_call_super(argc, argv));
@@ -2074,6 +2109,7 @@ InitVM_Enumerator(void)
rb_define_method(rb_cLazy, "slice_before", lazy_super, -1);
rb_define_method(rb_cLazy, "slice_after", lazy_super, -1);
rb_define_method(rb_cLazy, "slice_when", lazy_super, -1);
+ rb_define_method(rb_cLazy, "uniq", lazy_uniq, 0);
rb_define_alias(rb_cLazy, "force", "to_a");