|
Boost : |
Subject: Re: [boost] [fusion] undocumented sequence requirement: convert
From: Eric Niebler (eric_at_[hidden])
Date: 2012-08-28 02:06:26
On 8/23/2012 7:35 AM, Joel de Guzman wrote:
> On 8/23/2012 7:57 PM, Mathias Gaunard wrote:
>> On 23/08/2012 05:39, Joel de Guzman wrote:
>>
>>> which result_of::convert calls. Here's an example for vector:
>>>
>>> struct vector_tag;
>>>
>>> namespace extension
>>> {
>>> template <typename T>
>>> struct convert_impl;
>>>
>>> template <>
>>> struct convert_impl<vector_tag>
>>> {
>>> template <typename Sequence>
>>> struct apply
>>> {
>>> typedef typename
>>> detail::as_vector<result_of::size<Sequence>::value> gen;
>>> typedef typename gen::
>>> template apply<typename
>>> result_of::begin<Sequence>::type>::type
>>> type;
>>>
>>> static type call(Sequence& seq)
>>> {
>>> return gen::call(fusion::begin(seq));
>>> }
>>> };
>>> };
>>> }
>>>
>>> Pretty much straightforward. I think it is safe to use this extension
>>> mechanism. It has been stable for a long time now. Surely, that is
>>> not an excuse for it being undocumented though. At any rate, I
>>> added this in my TODO list.
>>
>> Any reason not to make the vector version the default?
>
> No, the result should be the target sequence type identified by
> its tag.
I managed to implement this customization point for proto, but it wasn't
easy, and I hope we can find a better solution. The problem is that,
although a proto expression is a fusion sequence of expressions, a
fusion sequence of expressions can't be turned into a proto expression
without additional information: the tag and the domain. I worked around
the problem by making the fusion_tag of proto expressions a template and
parameterizing it on the expression's tag and domain. That way, the
customization point can be implemented like this:
// Note: proto_expr must encode Tag and Domain for
// convert_impl to be implementable for proto.
template<typename Tag, typename Domain>
struct convert_impl<proto::tag::proto_expr<Tag, Domain> >
{
template<typename Sequence>
struct apply
{
typedef
typename proto::result_of::unpack_expr<
Tag
, Domain
, Sequence
>::type
type;
static type call(Sequence& seq)
{
return proto::unpack_expr<Tag, Domain>(seq);
}
};
};
IMO, this is less than ideal. In this case, it so happens that tag and
domain are pure compile-time information, and can be bundled with the
fusion tag. Generally, that won't be the case. Any type that models a
more refined concept than Fusion[xxx]Sequence can have additional
requirements that would be effectively sliced off by round-tripping
through this customization point.
Joel, do you have thoughts about this? Would extensible Fusion sequences
solve this?
-- Eric Niebler BoostPro Computing http://www.boostpro.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk