summaryrefslogtreecommitdiff
path: root/enumerator.c
diff options
context:
space:
mode:
authorShugo Maeda <shugo@ruby-lang.org>2019-06-21 17:27:20 +0900
committerShugo Maeda <shugo@ruby-lang.org>2019-06-21 17:42:27 +0900
commit702cf3ec9051914c8ef5a353580e0e74f7ec7005 (patch)
treeb75f662ba24b5ec7a86c1f8688a5713663ccd4b0 /enumerator.c
parent35392ff0a00934ec02558305b7be8dffe6420d30 (diff)
Enumerator::Lazy should support filter_map
Fixes [Bug #15949]
Diffstat (limited to 'enumerator.c')
-rw-r--r--enumerator.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/enumerator.c b/enumerator.c
index c37c8af..3fb953c 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -2060,6 +2060,37 @@ lazy_filter_map(VALUE obj)
}
static struct MEMO *
+lazy_filter_map_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
+{
+ VALUE value = lazyenum_yield_values(proc_entry, result);
+ if (!RTEST(value)) return 0;
+ LAZY_MEMO_SET_VALUE(result, value);
+ LAZY_MEMO_RESET_PACKED(result);
+ return result;
+}
+
+static const lazyenum_funcs lazy_filter_map_funcs = {
+ lazy_filter_map_proc, 0,
+};
+
+/*
+ * call-seq:
+ * lazy.filter_map { |obj| block } -> lazy_enumerator
+ *
+ * Like Enumerable#filter_map, but chains operation to be lazy-evaluated.
+ */
+
+static VALUE
+lazy_filter_map(VALUE obj)
+{
+ if (!rb_block_given_p()) {
+ rb_raise(rb_eArgError, "tried to call lazy filter_map without a block");
+ }
+
+ return lazy_add_method(obj, 0, 0, Qnil, Qnil, &lazy_filter_map_funcs);
+}
+
+static struct MEMO *
lazy_reject_proc(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
{
VALUE chain = lazyenum_yield(proc_entry, result);