Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move all elements which satisfy some condition from one container to another, i.e. I'm looking for some kind of "move_if"

Tags:

c++

c++11

c++14

Given

std::vector<T> first = /* some given data */, second;

I want to move all elements e which satisfy some condition cond(e) from first to second, i.e. something like

move_if(std::make_move_iterator(first.begin()),
    std::make_move_iterator(first.end()),
    std::back_inserter(second), [&](T const& e)
{
        return cond(e);
});

I wasn't able to establish this with the algorithms library. So, how can I do that?

like image 315
0xbadf00d Avatar asked Aug 22 '15 11:08

0xbadf00d


1 Answers

If the moved-from elements can stay where they are in first, then just use copy_if with move_iterator.

std::copy_if(std::make_move_iterator(first.begin()),
             std::make_move_iterator(first.end()),
             std::back_inserter(second), cond);

If the moved-from elements should be erased from first, I'd do

// partition: all elements that should not be moved come before 
// (note that the lambda negates cond) all elements that should be moved.
// stable_partition maintains relative order in each group
auto p = std::stable_partition(first.begin(), first.end(),
                               [&](const auto& x) { return !cond(x); });
// range insert with move
second.insert(second.end(), std::make_move_iterator(p),
                            std::make_move_iterator(first.end()));
// erase the moved-from elements.
first.erase(p, first.end());

Or partition_copy with a move_iterator, followed by assignment:

std::vector<T> new_first;
std::partition_copy(std::make_move_iterator(first.begin()),
                    std::make_move_iterator(first.end()),
                    std::back_inserter(second), std::back_inserter(new_first), cond);
first = std::move(new_first);
like image 77
T.C. Avatar answered Oct 20 '22 12:10

T.C.