Boost logo

Boost :

Subject: Re: [boost] [fusion] undocumented sequence requirement: convert
From: Joel de Guzman (joel_at_[hidden])
Date: 2012-08-22 23:39:46


On 8/23/2012 11:04 AM, Eric Niebler wrote:
> On 8/22/2012 7:45 PM, Joel de Guzman wrote:
>> On 8/23/2012 4:38 AM, Eric Niebler wrote:
>>>
>>> Say I have a valid fusion sequence. I want to use an mpl algorithm on
>>> it. I include boost/fusion/mpl.hpp and put a nested tag type in my
>>> sequence that is an alias for fusion::fusion_sequence_tag. So far, so
>>> good. Then I try to call mpl::pop_back on this sequence, and I find
>>> that, despite fulfilling all the documented requirements for Fusion
>>> ForwardSequence, the code fails to compile. That's because of this in
>>> boost/fusion/mpl/pop_back.hpp:
>>>
>>> template <>
>>> struct pop_back_impl<fusion::fusion_sequence_tag>
>>> {
>>> template <typename Sequence>
>>> struct apply
>>> {
>>> typedef typename
>>> fusion::result_of::pop_back<Sequence>::type
>>> result;
>>>
>>> typedef typename
>>> fusion::result_of::convert<
>>> typename fusion::detail::tag_of<Sequence>::type,
>>> result>::type
>>> type;
>>> };
>>> };
>>>
>>> My code doesn't compile because I haven't implemented the
>>> fusion::convert customization point. Where is that documented and what
>>> does it do?
>>
>> The basic problem is that MPL has this Extensible Sequence concept
>> that Fusion does not have. Keep in mind that mpl::pop_back requires
>> a Front Extensible Sequence and Fusion only guarantees adaptation
>> of an MPL Forward, Bidirectional or Random Access Sequence
>> (http://tinyurl.com/c7tmyfj). In this regard, we are actually
>> going beyond what's guaranteed by Fusion.
>>
>> That being said, I am really considering adding extensible sequences
>> into Fusion. The Deque, for example is a good example.
>
> The point remains: there is a required Fusion customization point that
> is not documented. (Or is it?)

No, it is not.

> So, should convert generate an mpl sequence? Or a Fusion sequence?

A Fusion sequence.

> Is
> there any post-condition regarding the tag type (or fusion_tag type?) of
> the resulting sequence?

The actual (undocumented) extension mechanism is:

     namespace extension
     {
         template <typename Tag>
         struct convert_impl;
     }

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.

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