|
Proto : |
Subject: [proto] _unpack transform (was: proto-11 progress report)
From: Eric Niebler (eric_at_[hidden])
Date: 2012-07-10 17:18:29
I just committed to the proto-11 codebase a new transform called
_unpack. You use it like this:
_unpack<f0(Tfx, f1(_)...)>
Where Tfx represents any transform (primitive or otherwise) f0 is any
callable or object type, and f1(_) is an object or callable transform.
The "..." denotes pseudo-pack expansion (although it's really an C-style
vararg ellipsis). The semantics are to replace "f1(_)..." with
"f1(_child<0>), f1(_child<1>), etc.".
With this, the _default transform is trivially implemented like this:
struct _default
: proto::or_<
proto::when<proto::terminal<_>, proto::_value>
, proto::otherwise<
proto::_unpack<eval(proto::tag_of<_>(), _default(_)...)>
>
>
{};
...where eval is:
struct eval
{
template<typename E0, typename E1>
auto operator()(proto::tag::plus, E0 && e0, E1 && e1) const
BOOST_PROTO_AUTO_RETURN(
static_cast<E0 &&>(e0) + static_cast<E1 &&>(e1)
)
template<typename E0, typename E1>
auto operator()(proto::tag::multiplies, E0 && e0, E1 && e1) const
BOOST_PROTO_AUTO_RETURN(
static_cast<E0 &&>(e0) * static_cast<E1 &&>(e1)
)
// Other overloads...
};
The _unpack transform is pretty general, allowing a lot of variation
within the pack expansion pattern. There can be any number of Tfx
transforms, and the wildcard can be arbitrarily nested. So these are all ok:
// just call f0 with all the children
_unpack<f0(_...)>
// some more transforms first
_unpack<f0(Tfx0, Tfx1, Tfx2, f1(_)...)>
// and nest the wildcard deeply, too
_unpack<f0(Tfx0, Tfx1, Tfx2, f1(f2(f3(_)))...)>
I'm still playing around with it, but it seems quite powerful. Thoughts?
Would there be interest in having this for Proto-current? Should I
rename it to _expand, since I'm modelling C++11 pack expansion?
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Proto list run by eric at boostpro.com