Fusion transform question

I started porting over some old codes that used hand-made MPL<->concrete object code to Fusion. I'm currently trying to have the following to work with no results so far : struct make_arg { template<class Type> struct result { typedef typename boost::add_reference<typename boost::add_const<Type>::type >::type type; }; }; template<class Args> struct tree { typedef Args children; typedef typename bf::result_of::transform<Args,make_arg>::type contents; template<class T0,class T1> tree( const T0& t0 , const T1& t1 ) : mArgs( /* what to put here ??? */ ) {} template<size_t I> typename bf::result_of::at_c<contents,I>::type get() const { return bf::at_c<I>(mArgs); } contents mArgs; }; int main() { int k=3; float u=7.2; tree< bf::vector<int, float> > tree(k,u); return 0; } The question - as stated - in the code is how to simply build the mArgs member from the t0,...,tn arguments ? Thanks in advance. -- Joel FALCOU Research Engineer @ Institut d'Electronique Fondamentale Université PARIS SUD XI France

AMDG Joel FALCOU wrote:
I started porting over some old codes that used hand-made MPL<->concrete object code to Fusion. I'm currently trying to have the following to work with no results so far :
Strange as it may seem, fusion::transform is not the right tool in this case, mpl::transform is what you want. fusion::transform is lazy. It returns a transform_view. mpl::transform works because fusion sequences /are/ mpl sequences. The default behavior of mpl::transform is to preserve the input sequence type. i.e. transforming an mpl::vector gives an mpl::vector, transforming an mpl::list gives an mpl::list, and transforming a fusion::vector gives a fusion::vector. #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/mpl.hpp> #include <boost/fusion/include/at.hpp> #include <boost/type_traits/add_reference.hpp> #include <boost/type_traits/add_const.hpp> #include <boost/type_traits/function_traits.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/back_inserter.hpp> namespace bf = boost::fusion; namespace mpl = boost::mpl; struct make_arg { template<class T> struct apply { typedef typename boost::add_reference< typename boost::add_const<T>::type >::type type; }; }; template<class Args> struct tree { typedef Args children; typedef typename mpl::transform<Args, make_arg>::type contents; template<class T0,class T1> tree( const T0& t0 , const T1& t1 ) : mArgs(t0, t1) {} template<size_t I> typename bf::result_of::at_c<contents,I>::type get() const { return bf::at_c<I>(mArgs); } contents mArgs; }; int main() { int k = 3; float u = 7.2f; tree< bf::vector<int, float> > tree(k, u); } In Christ, Steven Watanabe

Steven Watanabe a écrit :
Strange as it may seem, fusion::transform is not the right tool in this case, mpl::transform is what you want. fusion::transform is lazy. It returns a transform_view. mpl::transform works because fusion sequences /are/ mpl sequences. The default behavior of mpl::transform is to preserve the input sequence type. i.e. transforming an mpl::vector gives an mpl::vector, transforming an mpl::list gives an mpl::list, and transforming a fusion::vector gives a fusion::vector.
I just read the parts about the lazyness of fusion transformation. It indeed escpaed me for a few seconds. So basically the fusion transform are more suited for the runtime aprt of the code rather than the compile-time one ? -- Joel FALCOU Research Engineer @ Institut d'Electronique Fondamentale Université PARIS SUD XI France

AMDG Joel FALCOU wrote:
I just read the parts about the lazyness of fusion transformation. It indeed escpaed me for a few seconds. So basically the fusion transform are more suited for the runtime aprt of the code rather than the compile-time one ?
Right, fusion::transform is appropriate for mixed compile-time/run-time calculations. MPL is more appropriate for purely compile time constructs. In Christ, Steven Watanabe

2008/7/19 Steven Watanabe <watanabesj@gmail.com>:
AMDG
Joel FALCOU wrote:
I just read the parts about the lazyness of fusion transformation. It indeed escpaed me for a few seconds. So basically the fusion transform are more suited for the runtime aprt of the code rather than the compile-time one ?
Right, fusion::transform is appropriate for mixed compile-time/run-time calculations. MPL is more appropriate for purely compile time constructs.
Maybe this could be stated more clearly in the docs? The last part of fusion introduction section says: "For example, there are times when it is convenient to work solely on MPL using pure MPL sequences, then, convert them to Fusion sequences as a final step before actual instantiation of real runtime objects with data" This little line got stuck into my head, and at least in my experience using mpl algorithms&sequences is not only more convenient but also required most of the time, prior to instantiate any fusion sequence to do the runtime part. Adding something like: ! 'Choose MPL over fusion when doing pure type calculations. Once the static type calculation is finished, you can instantiate a fusion sequence (link to result_of::as_vector<S>') for the runtime part.' My 2 c.., / Christian Holmquist
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Christian Holmquist a écrit :
Adding something like: ! 'Choose MPL over fusion when doing pure type calculations. Once the static type calculation is finished, you can instantiate a fusion sequence (link to result_of::as_vector<S>') for the runtime part.'
This or a non-trivial exampel of MPL<->Fusion interaction that cover more than the MPl "adapted" page. -- Joel FALCOU Research Engineer @ Institut d'Electronique Fondamentale Université PARIS SUD XI France

Joel FALCOU wrote:
Christian Holmquist a écrit :
Adding something like: ! 'Choose MPL over fusion when doing pure type calculations. Once the static type calculation is finished, you can instantiate a fusion sequence (link to result_of::as_vector<S>') for the runtime part.'
This or a non-trivial exampel of MPL<->Fusion interaction that cover more than the MPl "adapted" page.
I think it is also confusing that fusion sequences are mpl sequences IF you include 'fusion/mpl.hpp', but not if you include 'fusion/adapted/mpl.hpp'. I would like to see that in the docs please (it took me some time to figure out). --John

John C. Femiani wrote:
Joel FALCOU wrote:
Christian Holmquist a écrit :
Adding something like: ! 'Choose MPL over fusion when doing pure type calculations. Once the static type calculation is finished, you can instantiate a fusion sequence (link to result_of::as_vector<S>') for the runtime part.'
This or a non-trivial exampel of MPL<->Fusion interaction that cover more than the MPl "adapted" page.
I think it is also confusing that fusion sequences are mpl sequences IF you include 'fusion/mpl.hpp', but not if you include 'fusion/adapted/mpl.hpp'. I would like to see that in the docs please (it took me some time to figure out).
Will do. Just out of curiosity, how did you figure it out? Which section in the docs did you look into first? Thanks! Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman wrote:
John C. Femiani wrote: <snip>
I think it is also confusing that fusion sequences are mpl sequences IF you include 'fusion/mpl.hpp', but not if you include 'fusion/adapted/mpl.hpp'. I would like to see that in the docs please (it took me some time to figure out).
Will do. Just out of curiosity, how did you figure it out? Which section in the docs did you look into first? Thanks! I'll answer in reverse order.
Which section in the docs did you look into first? First, I wanted the types in a fusion sequence as an mpl sequence. I googled, and found the introduction of the Fusion library, (which I had read before) :
Just out of curiosity, how did you figure it out? The concept assert failed because some MPL meta functions were missing. I realized that the fusion sequence could not be an mpl sequence, and
""" Fusion provides full round compatibility with MPL. Fusion sequences are fully conforming MPL sequences and MPL sequences are fully compatible with Fusion. You can work with Fusion sequences on MPL if you wish to work solely on types. In MPL, Fusion sequences follow MPL's sequence-type preserving semantics (i.e. algorithms preserve the original sequence type. e.g. transforming a vector returns a vector). You can also convert from an MPL sequence to a Fusion sequence. For example, there are times when it is convenient to work solely on MPL using pure MPL sequences, then, convert them to Fusion sequences as a final step before actual instantiation of real runtime objects with data. You have the best of both worlds. """" which led me to think I could just plunk a fusion sequence in wherever an MPL sequence already worked. I wanted to make sure every element in the fusion sequence passed a concept check, so I did this: //--------------------------- //in a header, in a detail namespace with some 'using mpl::' statements. template<class Seq, class Op> struct FusedConcept: inherit_linearly<typename transform<Seq, Op>::type, inherit<_1, _2> >::type {}; //in a test function, with some 'using' statements. //This works BOOST_CONCEPT_ASSERT((FusedConcept<mpl::vector<int, long>, Integer<_1> >)); //This fails BOOST_CONCEPT_ASSERT((FusedConcept< fusion::vector<int, long>, Integer<_1> >)); //----------------------------- that the mpl specializations must be added in some header I had not yet included. I knew already about adapted/mpl, and the documentation for that really only showed how I could use mpl from fusion. Including 'adapted/mpl.hpp' did not work. I did a 'Find in files' for "namespace mpl{", and I found that you were adding to the namespace from files in an 'mpl' directory directly under fusion (i.e. not just under fusion/adapted). Then I noticed another 'mpl.hpp' file sitting right there and I realized what it must be for. Once I added the line: #include <boost/fusion/mpl.hpp> to the header for FusedConcept, everything worked. --John

John C. Femiani wrote:
Joel de Guzman wrote:
John C. Femiani wrote: <snip>
I think it is also confusing that fusion sequences are mpl sequences IF you include 'fusion/mpl.hpp', but not if you include 'fusion/adapted/mpl.hpp'. I would like to see that in the docs please (it took me some time to figure out).
Will do. Just out of curiosity, how did you figure it out? Which section in the docs did you look into first? Thanks! I'll answer in reverse order.
Which section in the docs did you look into first? First, I wanted the types in a fusion sequence as an mpl sequence. I googled, and found the introduction of the Fusion library, (which I had read before) :
[snip long story]
to the header for FusedConcept, everything worked.
Ok, sorry for the troubles. I'll improve the docs to make this info easier to find. It is indeed lacking. Thanks for your support. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman wrote:
John C. Femiani wrote:
Joel de Guzman wrote:
John C. Femiani wrote: <snip>
I think it is also confusing that fusion sequences are mpl sequences IF you include 'fusion/mpl.hpp', but not if you include 'fusion/adapted/mpl.hpp'. I would like to see that in the docs please (it took me some time to figure out).
Will do. Just out of curiosity, how did you figure it out? Which section in the docs did you look into first? Thanks! I'll answer in reverse order.
Which section in the docs did you look into first? First, I wanted the types in a fusion sequence as an mpl sequence. I googled, and found the introduction of the Fusion library, (which I had read before) :
[snip long story]
to the header for FusedConcept, everything worked.
Ok, sorry for the troubles. I'll improve the docs to make this info easier to find. It is indeed lacking. Thanks for your support.
Ok, done. I added this to the adapted docs: [heading Header] #include <boost/fusion/adapted.hpp> #include <boost/fusion/include/adapted.hpp> Fusion sequences may also be adapted as fully conforming __mpl__ sequences (see __intrinsics__). That way, we can have 2-way adaptation to and from __mpl__ and Fusion. To make Fusion sequences fully conforming __mpl__ sequences, include: #include <boost/fusion/mpl.hpp> If you want bi-directional adaptation to and from __mpl__ and Fusion, simply include: #include <boost/fusion/include/mpl.hpp> The header includes all the necessary headers. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman wrote:
Ok, done. I added this to the adapted docs:
[heading Header]
#include <boost/fusion/adapted.hpp> #include <boost/fusion/include/adapted.hpp>
Fusion sequences may also be adapted as fully conforming __mpl__ sequences (see __intrinsics__). That way, we can have 2-way adaptation to and from __mpl__ and Fusion. To make Fusion sequences fully conforming __mpl__ sequences, include:
#include <boost/fusion/mpl.hpp>
If you want bi-directional adaptation to and from __mpl__ and Fusion, simply include:
#include <boost/fusion/include/mpl.hpp>
The header includes all the necessary headers. Great! Thanks, that definitely would have helped me out.
--John

Christian Holmquist wrote:
This little line got stuck into my head, and at least in my experience using mpl algorithms&sequences is not only more convenient but also required most of the time, prior to instantiate any fusion sequence to do the runtime part.
Adding something like: ! 'Choose MPL over fusion when doing pure type calculations. Once the static type calculation is finished, you can instantiate a fusion sequence (link to result_of::as_vector<S>') for the runtime part.'
Done. Added that to the docs as a footnote. Cheers, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net
participants (5)
-
Christian Holmquist
-
Joel de Guzman
-
Joel FALCOU
-
John C. Femiani
-
Steven Watanabe