[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); }
} hb_filter HB_UNUSED;
template <typename Redu, typename TValue>
template <typename Redu, typename InitT>
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,
hb_enable_if (hb_is_iterator (Iter))>
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 <typename Redu, typename TValue> hb_reduce_t<Redu, TValue>
operator () (Redu&& r, TValue init_value) const
{ return hb_reduce_t<Redu, TValue> (r, init_value); }
template <typename Redu, typename InitT>
hb_reduce_t<Redu, InitT>
operator () (Redu&& r, InitT init_value) const
{ return hb_reduce_t<Redu, InitT> (r, init_value); }
} hb_reduce HB_UNUSED;

View File

@ -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
;