Boost logo

Boost :

Subject: Re: [boost] [fusion] undocumented sequence requirement: convert
From: Joel de Guzman (joel_at_[hidden])
Date: 2012-08-29 03:58:47


On 8/28/2012 2:06 PM, Eric Niebler wrote:
> 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?

In my mind, if we have forward and backward extensible Fusion sequences
(and we should), the proper CP will be fusion::pop_back_impl. Fusion's
mpl extensions, e.g. mpl::pop_back_impl will simply call fusion's
CP for known (traits) forward and backward extensible Fusion sequences
and default to the original behavior for non-extensible Fusion sequences
(as before).

Convert is another story. And as you pointed out, it looks like it
needs more info than is provided in the CP. But still I lack proper
understanding of this particular use-case. In general, convert should
be able to convert any fusion sequence T (including MPL sequences)
to another sequence U.

Regards,

-- 
Joel de Guzman
http://www.boostpro.com
http://boost-spirit.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk