ericniebler / range-v3

Range library for C++14/17/20, basis for C++20's std::ranges
Other
4.15k stars 439 forks source link

transformations of ranges of tuple-like objects #1460

Open rbrugo opened 4 years ago

rbrugo commented 4 years ago

Hi, I could be wrong, but currently if I want to transform a tuple-like object I have to do something like

auto result1 = range_of_tuples | views::transform([&f](auto && tuple) {
    auto [x, y, z] = tuple;
    return f(x, y, z);
});

auto result2 = range_of_tuples | views::transform([&f](auto && tuple) {
    return std::apply(f, tuple);
});

I think it would be nice if it were possible to write

auto result1 = range_of_tuples | views::transform(f);
auto result2 = range_of_tuples | views::apply(f);

by having an overload for transform_view::operator() which tries to std::apply if it is not possible to INVOKE, or a completely new view if that is not possible

ericniebler commented 4 years ago

I like this idea.

beojan commented 4 years ago

Until that time, I think this (from Boost HOF) can help.

Talkless commented 2 years ago

+1 from transform_apply of some sort.

Some people suggest create wrappers: https://stackoverflow.com/a/65855073, but having this as a ranges "vocabulary" view would be awesome.

Talkless commented 2 years ago

Same for filtering. Currently I have:

    //find first empty slot in the grid, starting from top left, moving in rows to the right
    for (const auto& [row, column]: rv::cartesian_product(rv::indices(gridHeight), rv::indices(gridWidth))
         | rv::filter([this](const auto& tuple){ const auto [row, column] = tuple; return !containsSlot(column, row); })) {
        return QPoint{column, row};
    }

So instead of

rv::filter([this](const auto& tuple){ const auto [row, column] = tuple; return !containsSlot(column, row); }

It would be nice to have something like this:

rv::filter_apply([this](int row, int column){ return !containsSlot(column, row); }
JohelEGP commented 2 years ago

In light of that, rather than adding N view_apply, it'd be better to just have a predicate wrapper applied(f) that does std::apply(f,e).

brevzin commented 2 years ago

Until that time, I think this (from Boost HOF) can help.

Not apply, unpack.

Talkless commented 2 years ago

So it would look like this?

| filter(unpack(mylambda)) | ...