Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost Hana filter a constexpr tuple

Tags:

c++

boost

Super basic question about Boost Hana.

From the examples it seems I should be able to do the following:

int main() {
    constexpr auto a = boost::hana::make_tuple(-1, 4, 5, -4);
    constexpr auto b = boost::hana::filter(a, [](int elem) constexpr { boost::hana::bool_c<(elem > 0)>;});
}

However, I get

error: 'elem' is not a constant expression

which seems weird because I added constexpr wherever I could...

Is this at all possible? Or am I just missing something?

Note: I realize that you can achieve this with constexpr functions or something, but I would like to see how to do it with Hana as well, for educational purposes.

like image 334
Nibor Avatar asked Mar 02 '26 17:03

Nibor


1 Answers

The return type must be statically deducible. However, you are returning different types depending on the argument.

You could do it, but not using hana::filter because that specifically moves into the runtime domain by putting the (statically known) tuple elements in (runtime) function arguments.

As soon as your predicate depends on more than statically known information (i.e. the types of the elements), it won't be constantly evaluated. The examples document how it could be used:

static_assert(hana::filter(hana::make_tuple(1, 2.0, 3, 4.0), is_integral) == hana::make_tuple(1, 3), "");
static_assert(hana::filter(hana::just(3), is_integral) == hana::just(3), "");
BOOST_HANA_CONSTANT_CHECK(hana::filter(hana::just(3.0), is_integral) == hana::nothing);

On the other hand, you can have your cake and eat it if you move the elements to the compile time domain:

Live On Coliru

constexpr auto a = hana::make_tuple(-1_c, 4_c, 5_c, -4_c);

constexpr auto b = hana::filter(                                                               //
    a,                                                                               //
    [](auto elem) constexpr { return std::integral_constant<bool, (elem() > 0)>{}; } //
);

std::cout << "a:" << hana::size(a) << "\n";
std::cout << "b:" << hana::size(b) << "\n";

Prints

a:4
b:2
like image 197
sehe Avatar answered Mar 05 '26 05:03

sehe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!