
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