diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 04261bd2d..f23904c22 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -348,31 +348,33 @@ static const struct { return hb_filter_iter_factory_t (p, f); } } hb_filter HB_UNUSED; -template +template struct hb_reduce_t { - hb_reduce_t (Redu r, TValue init_value) : r (r), init_value (init_value) {} + hb_reduce_t (Redu r, InitT init_value) : r (r), init_value (init_value) {} template - TValue + hb_enable_if (hb_is_iterator (Iter)), + typename AccuT = decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))> + AccuT operator () (Iter it) const { - TValue value = init_value; + AccuT value = init_value; for (; it; ++it) - value = r (*it, value); + value = r (value, *it); return value; } private: Redu r; - TValue init_value; + InitT init_value; }; static const struct { - template hb_reduce_t - operator () (Redu&& r, TValue init_value) const - { return hb_reduce_t (r, init_value); } + template + hb_reduce_t + operator () (Redu&& r, InitT init_value) const + { return hb_reduce_t (r, init_value); } } hb_reduce HB_UNUSED; diff --git a/src/test-iter.cc b/src/test-iter.cc index e142c560a..071edabee 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -156,9 +156,33 @@ main (int argc, char **argv) + hb_iter (src) | hb_map ([&] (int i) -> int { return 1; }) - | hb_reduce ([&] (int acc, int cur) -> int { return acc + cur; }, 2) + | hb_reduce ([&] (int acc, int value) -> int { return acc; }, 2) ; + unsigned int temp1 = 10; + unsigned int temp2 = 0; + hb_map_t *result = + + hb_iter (src) + | hb_map ([&] (int i) -> hb_set_t * + { + hb_set_t *set = hb_set_create (); + for (unsigned int i = 0; i < temp1; ++i) + hb_set_add (set, i); + temp1++; + return set; + }) + | hb_reduce ([&] (hb_map_t *acc, hb_set_t *value) -> hb_map_t * + { + hb_map_set (acc, temp2++, hb_set_get_population (value)); + // This is not a memory managed language, take care! + hb_set_destroy (value); + return acc; + }, hb_map_create ()) + ; + // The result should be something like 0->10, 1->11, ..., 9->19 + assert (hb_map_get (result, 9) == 19); + hb_map_destroy (result); + + hb_iter (src) | hb_drain ;