-
Notifications
You must be signed in to change notification settings - Fork 82
Provide a proper equivalent of mpl::eval_if #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
As far as I can see that's just
|
No, that won't retain laziness when composed. See the linked code snippet, it goes like this:
If
|
Ah, right, it needs to be
Mp11 has Also, the conditions are evaluated in both cases. Although in our specific example there doesn't seem to be any need for laziness, as all the conditions and results can be instantiated without fear. |
I would like the conditions to be instantiated only on demand, as it happens with |
I managed to convert the linked snippet to this, but it took me about half an hour to get to this, and the solution doesn't scale as you can't nest |
Not sure why nesting mp_defer wouldn't work. E.g. here you aren't SFINAE-ing properly at top level because of the unconditional nested type, but I don't see why an mp_defer there wouldn't work. Instead of
do
But all this deferral is unnecessary here; the conditions, and the results, don't fail, so there's no problem if they are instantiated eagerly. You can just do this
maybe with the conjunctions replaced with |
In this case, I want to avoid unnecessary instantiations for performance reasons rather than correctness. That's how MPL code works and I definitely don't want to regress compared to that. But ensuring correctness (i.e. not breaking compilation due to unwanted template instantiation) may also be a goal in other use cases. Let's assume that minimizing instantiations is a hard requirement from user.
This is not the issue I'm having. The issue is how to write multiple nested Here is the original code, after converting the inner
This code fulfills the requirements that I listed above - each condition and branch is only evaluated on demand. Now I try to convert it to Boost.MP11. First, let's try the direct approach, by converting each
This works, but the condition marked with (1) is always instantiated because its associated
And that doesn't work because the outer
But this is getting even more obscure and difficult to maintain. Let's try
But this explodes because In the end I figured out to use But do you see the problem? Most Boost.MP11 constructs are eager to instantiate their template parameters, and trying to prevent that is really painful. And |
Pretty much all. Mp11 is alias based, and aliases are always eager. This generally delivers better performance despite doing more instantiations. E.g. Or for another example, The purpose of
This is generally solved by using What I would do here is the "stupid" and straightforward
|
I tried benchmarking 100 instantiations of MPL:
My MP11:
Your MP11:
|
There are cases when I find
mpl::eval_if
much easier to use thanmp11::mp_eval_if
,mp11::mp_if
,mp11::mp_cond
andmp11::mp_defer
. For example, converting something like this to Boost.MP11 is rather painful if one wants to preserve lazy evaluation of alleval_if
branches in the tree. One particular pain point is thatmp_defer
does not compose with anything that takes template template parameters, includingmp_eval_if
andmp_defer
itself.It would be helpful if Boost.MP11 provided a direct equivalent of
mpl::eval_if
. Specifically, a metafunction that would lazily instantiate each of the branches depending on the condition, where the branches implement the::type
protocol. In general, I think the library could use a better support for the::type
protocol.The text was updated successfully, but these errors were encountered: