On Wed, Feb 22, 2017 at 12:38 AM, Peter Dimov via Boost < boost@lists.boost.org> wrote:
Bruno Dutra wrote:
mp_transform<std::add_const_t, std::shared_ptr<X>> //
std::shared_ptr<X const>
Your example is implemented in Metal like this
using _ = metal::transform<metal::lambda<std::add_const_t>, metal::as_list<std::shared_ptr<X>>>; // metal::list<X const> metal::apply<metal::lambda<std::shared_ptr>, _> // std::shared_ptr<X
const>
And suppose that std::shared_ptr<X> is given to you as a type P, and you
don't know if it's shared_ptr or not, so you can't use metal::lambda<std::shared_ptr>? Excellent observation! We need metal::unwrap https://github.com/brunocodutra/metal/issues/58
Right, SFINAEability does make things harder. There's the option of taking everything and always returning metal::list. Numbers however pose fewer issues if I'm not mistaken. You just take N::value instead of requiring metal::number.
That is mostly true in the context of SFINAE friendliness, but that is not all that there's to it. Throughout Metal, the concept of equality among Values is expressed by metal::same, which is just a n-ary generalization of std::is_same. Because any type is a Value, it follows that all the information embedded in it must be available in its type signature as far as Metal is concerned. This is what guarantees pattern matching. This is also the reason why metal::number<N> is defined as an alias to std::integral_constant<metal::int_, N>, where metal::int_ is an unspecified integral type. This might seem unimportant, but was actually designed to solve an inconvenience of MPL, which depends on three different metafunctions to express the very same concept of equality, namely mpl::is_same, mpl::equal and mpl::equal_to. At any rate, metal::as_number conveniently transforms anything that has a nested ::value into a Number, provided that it fits metal::int_.