0

In ADSP Podcast Episode 91 (2022-08-19, around 14:30 ... 16:30) Bryce Lelbach and Conor Hoekstra talk about an example application of the (hopefully) upcoming C++23 ranges views zip_transform and repeat: scaling a range of values by the (non-zero) minimum value of that range.

Since to my knowledge at the time of writing, no library of any compiler implements these yet (and no link was given), I wonder how to implement it. The closest I came up with, was

auto scale_by_min(auto&& range)
{
    auto m = std::ranges::min(range);
    return std::views::zip_transform(
        range,
        std::views::repeat(m),
        [](auto x, auto min)
        {
            return x / min;
        }
    );
} 

((non-working) example in godbolt). Did I get it right?

Edit / Clarification:

Replacing the return statement by

return range | std::views::transform([m](auto x){ return x / m; });

it works in C++20, also without zip_transform and repeat, as correctly stated in a comment. This question is not about conciseness, style, or meaningfulness of the example. I just try to get the syntax right for using the upcoming ranges-views.

René Richter
  • 3,839
  • 3
  • 34
  • 42

1 Answers1

2

Did I get it right?

No. zip_transform accepts variadic template arguments as input ranges, the first argument of zip_transform must be the transform functor, so you should

auto m = std::ranges::min(range);
return std::views::zip_transform(
  std::divides{},
  range,
  std::views::repeat(m)
);

It's worth noting that views::repeat(m) gives you an infinite range, which makes zip_transform_view not model sized_range. You can pass the second parameter of repeat_view by detecting whether the range is sized_range, e.g.

auto m = std::ranges::min(range);
auto repeat = [&] {
  if constexpr (std::ranges::sized_range<decltype(range)>)
    return std::views::repeat(m, std::ranges::size(range));
  else
    return std::views::repeat(m);
}();
return std::views::zip_transform(std::divides{}, range, repeat);

which makes zip_transform_view preserve the properties of sized_range.

康桓瑋
  • 33,481
  • 5
  • 40
  • 90