edouarda/brigand

remove_if seems not to work as expected

martin5233 opened this issue · 3 comments

When trying to remove items from a set via remove_if, this does not generate the expected result:

struct A {};
struct B {};
struct C {};

using Result = brigand::remove_if<brigand::set<A, B, C>, brigand::has_key<brigand::set<A>, brigand::_1>>;

From my understanding Result should not contain A in this case, but for some reason it does. I tried this with GCC 4.9, 5.4 and 6.2. Is this a bug or do I expect something wrong? I tried this with Brigard 1.3.0

Why not erase the item from the set directly?

Are you sure your lambda doesn't always return false?

Thanks for your quick reply. I do not use erase, because I actually want to remove all entries, which are contained in one set, from another set. I only condensed this to the above example to make it small and easily understandable.

Regarding the lambda I tried the following:
static_assert(brigand::has_key<brigand::set<A>, A>::value, "Fail 1");
compiles successfully, but
static_assert(brigand::apply<brigand::has_key<brigand::set<A>, brigand::_1>, A>::value, "Fail 2");
fails to compile. Do you have any idea, what's going wrong here?

Just a note: I'm really astonished what you created with the Brigand library. I used Boost::mpl a lot, but Brigand is so small and elegant!

A very late reply, but your problem is that has_key is eager, so brigand::has_key<brigand::set<A>, brigand::_1> tests whether the actual class brigand::_1 is in the set, which it is not. A working form of the final example is

static_assert(brigand::apply<brigand::bind<brigand::has_key, brigand::pin<brigand::set<A>>, brigand::_1>, A>::value, "Fail 2");