Boost logo

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