mpl/fusion: metafunction to 'rangify'

I am making small progress in my attempt to generate a new mpl sequence that I will use to read from a stream. The following code fails to compile: #include <boost/tuple/tuple.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/mpl/transform.hpp> #include <boost/fusion/adapted/struct/adapt_struct.hpp> #include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/mpl.hpp> // makes params a MPL sequence #include <boost/fusion/support/is_sequence.hpp> #include <boost/fusion/include/is_sequence.hpp> struct params { double d1; double d2; double d3; unsigned int i4; unsigned int i5; unsigned int i6; unsigned int i7; }; BOOST_FUSION_ADAPT_STRUCT( params, (double, d1) (double, d2) (double, d3) (unsigned int, i4) (unsigned int, i5) (unsigned int, i6) (unsigned int, i7) ) BOOST_MPL_ASSERT(( boost::fusion::traits::is_sequence<params> )); // passes template <typename T1> struct rangify { typedef boost::tuple<T1, T1, T1> type; /// min max incr }; template <typename T> struct fixed_or_range { typedef struct { union { T fixed; typename rangify<T>::type range; }; bool is_fixed; } type; }; typedef boost::mpl::transform< params, fixed_or_range<boost::mpl::_> >::type params_fixed_or_range; I understand that after the macro BOOST_FUSION_ADAPT_STRUCT , params is a fusion sequence. Including <boost/fusion/mpl.hpp> made params a MPL sequence, and therefore I can call boost::mpl::transform<> on it. The compilation error is c:\program files (x86)\boost_1_41_0\boost\mpl\clear.hpp(30) : error C2903: 'apply' : symbol is neither a class template nor a function template 1> c:\program files (x86)\boost_1_41_0\boost\mpl\transform.hpp(113) : see reference to class template instantiation 'boost::mpl::clear<Sequence>' being compiled 1> with 1> [ 1> Sequence=params 1> ] 1> c:\program files (x86)\boost_1_41_0\boost\mpl\eval_if.hpp(41) : see reference to class template instantiation 'boost::mpl::transform1<P1,P2,P3>' being compiled 1> with 1> [ 1> P1=params, 1> P2=fixed_or_range<boost::mpl::_1>, 1> P3=boost::mpl::na 1> ] 1> c:\program files (x86)\boost_1_41_0\boost\mpl\transform.hpp(138) : see reference to class template instantiation 'boost::mpl::eval_if<C,F1,F2>' being compiled 1> with 1> [ 1> C=boost::mpl::or_<boost::mpl::is_na<boost::mpl::na>,boost::mpl::is_lambda_ex pression<fixed_or_range<boost::mpl::_1>>,boost::mpl::not_<boost::mpl::is_seq uence<fixed_or_range<boost::mpl::_1>>>>, 1> F1=boost::mpl::transform1<params,fixed_or_range<boost::mpl::_1>,boost::mpl:: na>, 1> F2=boost::mpl::transform2<params,fixed_or_range<boost::mpl::_1>,boost::mpl:: na,boost::mpl::na> 1> ] 1> c:\users\hich\documents\visual studio 2008\projects\test\test1\main.cpp(51) : see reference to class template instantiation 'boost::mpl::transform<Seq1,Seq2OrOperation>' being compiled 1> with 1> [ 1> Seq1=params, 1> Seq2OrOperation=fixed_or_range<boost::mpl::_1> 1> ] Regards,

Hicham Mouline schrieb:
I am making small progress in my attempt to generate a new mpl sequence that I will use to read from a stream.
The following code fails to compile: [snip]
You should work with a copy of fusion's trunk. See http://thread.gmane.org/gmane.comp.lib.boost.user/53893/ for more information. Unfortunately there is another problem. mpl::transform internally instantiates mpl::clear. Fusion's implementation of mpl::clear only works for the built-in container. I think fusion's mpl::clear should rather forward to fusion::clear and fusion::clear should return a simple, empty container that models the same category as the sequence to be cleared. At the moment, fusion::clear returns fusion::vector0<> in any case. -Christopher

-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of Christopher Schmidt Sent: 22 December 2009 22:50 To: boost-users@lists.boost.org Subject: Re: [Boost-users] mpl/fusion: metafunction to 'rangify'
Hicham Mouline schrieb:
I am making small progress in my attempt to generate a new mpl sequence that I will use to read from a stream.
The following code fails to compile: [snip]
You should work with a copy of fusion's trunk. See
http://thread.gmane.org/gmane.comp.lib.boost.user/53893/
for more information. Exactly what I just discovered. I copied the fix in fusion/adapted/struct/adapt_struct.hpp The is_sequence works but as you say below, mpl::transform doesn't.
Unfortunately there is another problem. mpl::transform internally instantiates mpl::clear. Fusion's implementation of mpl::clear only works for the built-in container. I think fusion's mpl::clear should rather forward to fusion::clear and fusion::clear should return a simple, empty container that models the same category as the sequence to be cleared. At the moment, fusion::clear returns fusion::vector0<> in any case.
-Christopher Stjepan Rajko had a similar problem back in Feb09 and seems to have solved it, but I don't understand. He adds a bit of code in (see pastebin) http://lists.boost.org/boost-users/2009/02/45051.php
In the meantime, can I just use the fusion::transform on the adapted struct instead of mpl::transform? What I really want is a new fusion sequence the elements of which are the result of my metafunction applied on the elements of the adapted struct. So this seemed to be a mpl::transform job. Rds,

Hicham Mouline schrieb:
Hicham Mouline schrieb:
I am making small progress in my attempt to generate a new mpl sequence that I will use to read from a stream.
The following code fails to compile: [snip]
You should work with a copy of fusion's trunk. See
http://thread.gmane.org/gmane.comp.lib.boost.user/53893/
for more information. Exactly what I just discovered. I copied the fix in fusion/adapted/struct/adapt_struct.hpp The is_sequence works but as you say below, mpl::transform doesn't.
Unfortunately there is another problem. mpl::transform internally instantiates mpl::clear. Fusion's implementation of mpl::clear only works for the built-in container. I think fusion's mpl::clear should rather forward to fusion::clear and fusion::clear should return a simple, empty container that models the same category as the sequence to be cleared. At the moment, fusion::clear returns fusion::vector0<> in any case.
-Christopher Stjepan Rajko had a similar problem back in Feb09 and seems to have solved it, but I don't understand. He adds a bit of code in (see pastebin) http://lists.boost.org/boost-users/2009/02/45051.php
This code provides a specialization of fusion's mpl::clear for adapted arrays. This makes his particular use-case compile fine but this does not solve the general problem.
In the meantime, can I just use the fusion::transform on the adapted struct instead of mpl::transform? What I really want is a new fusion sequence the elements of which are the result of my metafunction applied on the elements of the adapted struct. So this seemed to be a mpl::transform job.
This should work fine: struct make_fixed_or_range { template<typename Sig> struct result; template<typename Self,typename Arg> struct result<Self(Arg)> { typedef fixed_or_range<Arg> type; }; template<class Arg> typename result<make_fixed_or_range(Arg)>::type operator()(Arg); }; typedef boost::fusion::result_of::as_vector<boost::fusion::result_of::transform<params,make_fixed_or_range>::type>::type params_fixed_or_range; -Christopher

-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of Christopher Schmidt Sent: 22 December 2009 23:24 To: boost-users@lists.boost.org Subject: Re: [Boost-users] mpl/fusion: metafunction to 'rangify'
In the meantime, can I just use the fusion::transform on the adapted struct instead of mpl::transform? What I really want is a new fusion sequence the elements of which are the result of my metafunction applied on the elements of the adapted struct. So this seemed to be a mpl::transform job.
This should work fine:
struct make_fixed_or_range { template<typename Sig> struct result;
template<typename Self,typename Arg> struct result<Self(Arg)> { typedef fixed_or_range<Arg> type; };
template<class Arg> typename result<make_fixed_or_range(Arg)>::type operator()(Arg); };
typedef boost::fusion::result_of::as_vector<boost::fusion::result_of::transform< params,make_fixed_or_range>::type>::type params_fixed_or_range;
-Christopher
It does. Of course, the return type of fusion::transform contains the compile-time information required. Thanks very much, Now I'll look at spirit (and some magic code to generate the Qi parser for this new sequence) to fill it up with values from an input stream. Thanks again, Rds,
participants (2)
-
Christopher Schmidt
-
Hicham Mouline