[iter] hb_reduce, accumulator with a different type

This commit is contained in:
Ebrahim Byagowi 2019-04-02 00:30:06 +04:30 committed by Behdad Esfahbod
parent e526414c75
commit b8642087e6
2 changed files with 37 additions and 11 deletions

View File

@ -348,31 +348,33 @@ static const struct
{ return hb_filter_iter_factory_t<Pred, Proj> (p, f); } { return hb_filter_iter_factory_t<Pred, Proj> (p, f); }
} hb_filter HB_UNUSED; } hb_filter HB_UNUSED;
template <typename Redu, typename TValue> template <typename Redu, typename InitT>
struct hb_reduce_t 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 <typename Iter, template <typename Iter,
hb_enable_if (hb_is_iterator (Iter))> hb_enable_if (hb_is_iterator (Iter)),
TValue typename AccuT = decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>
AccuT
operator () (Iter it) const operator () (Iter it) const
{ {
TValue value = init_value; AccuT value = init_value;
for (; it; ++it) for (; it; ++it)
value = r (*it, value); value = r (value, *it);
return value; return value;
} }
private: private:
Redu r; Redu r;
TValue init_value; InitT init_value;
}; };
static const struct static const struct
{ {
template <typename Redu, typename TValue> hb_reduce_t<Redu, TValue> template <typename Redu, typename InitT>
operator () (Redu&& r, TValue init_value) const hb_reduce_t<Redu, InitT>
{ return hb_reduce_t<Redu, TValue> (r, init_value); } operator () (Redu&& r, InitT init_value) const
{ return hb_reduce_t<Redu, InitT> (r, init_value); }
} hb_reduce HB_UNUSED; } hb_reduce HB_UNUSED;

View File

@ -156,9 +156,33 @@ main (int argc, char **argv)
+ hb_iter (src) + hb_iter (src)
| hb_map ([&] (int i) -> int { return 1; }) | 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_iter (src)
| hb_drain | hb_drain
; ;