|
Boost : |
Subject: Re: [boost] [GSoC][MPL11] Post C++Now update
From: Louis Dionne (ldionne.2_at_[hidden])
Date: 2014-05-19 13:28:23
Joel de Guzman <djowel <at> gmail.com> writes:
>
> On 5/19/14, 4:41 AM, Louis Dionne wrote:
> > After discussing the issue several times during the week, I (and others)
> > think it might be possible to merge Fusion and the MPL into a single
> > library. I am currently trying to write a library that does that. Since
> > this constitutes a large reorientation, I created a new repository which
> > is available at [2]. Those with interest should consider subscribing to
> > the repository to be updated as I make progress.
>
> Been there tried that...
>
> This has been proposed several times in the past. I reiterate my
> position: MPL and Fusion are different beasts and it is not good for
> both to be merged (if it is at all possible). MPL does not have the
> runtime components that Fusion needs and Fusion has runtime
> components that MPL *does not* need.
This is true, the MPL does not _need_ a runtime component. Adding one should
be harmless if done correctly. There might be a performance penalty though,
but I'll benchmark that eventually.
> Also, because of the runtime aspects of Fusion, the semantics of
> algorithms do not make sense in MPL. Take the any algo for example:
>
> http://tinyurl.com/mk2whdo
>
> Note that odd in that example is a runtime operation. How do you
> unite that? It works only with fusion sequences (with values)
> and not with MPL sequences (with types). In MPL, that would be a
> type-only predicate.
As of writing this, here is what I am able to do [1]:
Purely runtime predicate
------------------------
struct odd {
template <typename T>
bool operator()(T t) const { return t % 2; }
};
assert(any(odd{}, list(1, 2)));
assert(!any(odd{}, list(2, 4)));
Constexpr predicate
-------------------
struct odd {
template <typename T>
constexpr bool operator()(T t) const { return t % 2; }
};
static_assert(any(odd{}, list(1, 2)), "");
static_assert(!any(odd{}, list(2, 4)), "");
Type-only predicate
-------------------
struct odd {
template <typename T>
constexpr auto operator()(T t) const { return t % int_<2>; }
};
static_assert(std::is_same<
decltype(any(odd{}, list(int_<1>, int_<2>))),
Bool<true>
>::value, "");
static_assert(std::is_same<
decltype(any(odd{}, list(int_<2>, int_<4>))),
Bool<false>
>::value, "");
The trick for the type-only predicate is that there exists an overload
template <int i, int j>
constexpr Int<i % j> operator%(Int<i>, Int<j>) { return {}; }
where Int<...> is the type of int_<...>. Since int_<...> is implicitly
constexpr convertible to int, one can just write the predicate as
struct odd {
template <typename T>
constexpr auto operator()(T t) const { return t % int_<2>; }
};
and use it in the three examples. So there is no code duplication and
purely compile-time functions can now also be used as runtime or constexpr
functions for free. This is a large gain IMO.
As far as I can see, everything that can be done with the MPL may also be
done with a variation of this technique. For an example, see [2].
> If you add values to MPL, it would be 1) unnecessarily more complex
> than it needs to be
I don't see why that should be, and my experience suggests something
different. Could you please expand on this point and/or provide evidence
backing this claim?
> and 2) the feature set would be comprised of very
> ugly mongrels.
Again, I don't see why that should be and my experience suggests that
this is not the case.
Regards,
Louis Dionne
[1]: https://github.com/ldionne/hana/blob/master/test/misc/fusion_any.cpp
[2]: https://github.com/ldionne/hana/blob/master/test/type/mpl_equivalent.cpp
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk