fusion struct adapt macro, construct the struct from a fusion vector

Hello, I have a struct params { ... }; and I have adapted it as a fusion sequence. However I can't construct a params from a boost::fusion::vector<> with the same types. const params p( v ); // v is a fusion::vector with the same type const params p = v; // both failed to compile Do I need to actually write a specific ctor for params? Will it change the result of the adapt macro? Can I iterate with an algorithm over the vector at runtime to assign to p from v? with fusion::for_each() I couldn't write the functor that would let me assign to p. Regards,

On 1/17/2010 10:02 PM, Hicham Mouline wrote:
Hello,
I have a struct params { ... };
and I have adapted it as a fusion sequence.
However I can't construct a params from a boost::fusion::vector<> with the same types.
const params p( v ); // v is a fusion::vector with the same type const params p = v; // both failed to compile
Of course you can't, unless your struct params has a template constructor that accepts fusion sequences -- that's easy enough to do. Keep in mind that the adapt macro is non-intrusive. What happens in your struct is your business.
Do I need to actually write a specific ctor for params?
Yes.
Will it change the result of the adapt macro?
No.
Can I iterate with an algorithm over the vector at runtime to assign to p from v? with fusion::for_each() I couldn't write the functor that would let me assign to p.
Yep. Perhaps you can use zip_view to iterate both sequences in parallel. E.g. for_each(zip(p, v), f). Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon

----- Original Message ----- From: "Joel de Guzman" <joel@boost-consulting.com> To: <boost-users@lists.boost.org> Sent: Monday, January 18, 2010 9:56 AM Subject: Re: [Boost-users] fusion struct adapt macro, construct the struct from a fusion vector
On 1/17/2010 10:02 PM, Hicham Mouline wrote:
Hello,
I have a struct params { ... };
and I have adapted it as a fusion sequence.
However I can't construct a params from a boost::fusion::vector<> with the same types.
const params p( v ); // v is a fusion::vector with the same type const params p = v; // both failed to compile
Of course you can't, unless your struct params has a template constructor that accepts fusion sequences -- that's easy enough to do. Keep in mind that the adapt macro is non-intrusive. What happens in your struct is your business.
Do I need to actually write a specific ctor for params?
Yes.
Will it change the result of the adapt macro?
No.
Can I iterate with an algorithm over the vector at runtime to assign to p from v? with fusion::for_each() I couldn't write the functor that would let me assign to p.
Yep. Perhaps you can use zip_view to iterate both sequences in parallel. E.g. for_each(zip(p, v), f).
I am trying to write code that is as independent of the struct as possible. The first thing that comes to my mind for the ctor is struct params { ...// there are 7 members, in the 100 or so different structs I will have, max 20 members maybe template <typename T1, ... typename T7> params(const fusion::vector<T1,...T7>& v); }; This probably isn't what you meant. How to generalize it to any fusion sequence? Is it possible to generalize the number of template args? Regards,

I am trying to write code that is as independent of the struct as possible. The first thing that comes to my mind for the ctor is
struct params { ...// there are 7 members, in the 100 or so different structs I will have, max 20 members maybe template <typename T1, ... typename T7> params(const fusion::vector<T1,...T7>& v); };
This probably isn't what you meant. How to generalize it to any fusion sequence? Is it possible to generalize the number of template args?
What about: template <typename Seq> params(Seq const& seq, typename boost::enable_if< fusion::traits::is_sequence<Seq> >::type* = NULL); ? Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com

----- Original Message ----- From: "Hartmut Kaiser" <hartmut.kaiser@gmail.com> To: <boost-users@lists.boost.org> Sent: Tuesday, January 19, 2010 9:25 AM Subject: Re: [Boost-users] fusion struct adapt macro,construct the struct from a fusion vector
I am trying to write code that is as independent of the struct as possible. The first thing that comes to my mind for the ctor is
struct params { ...// there are 7 members, in the 100 or so different structs I will have, max 20 members maybe template <typename T1, ... typename T7> params(const fusion::vector<T1,...T7>& v); };
This probably isn't what you meant. How to generalize it to any fusion sequence? Is it possible to generalize the number of template args?
What about:
template <typename Seq> params(Seq const& seq, typename boost::enable_if< fusion::traits::is_sequence<Seq>
::type* = NULL);
?
Fantastic. Here is the code I have (plz see below), but it seems there are issues with const-ness that I don't understand. For the case of 2 sequences, does zip return a sequence of vector2s each of which has only 2 const entries. In the assignelt functor, I tried casting const away but there is this error with the code below: boost/fusion/algorithm/iteration/detail/for_each.hpp:59: error: no match for call to '(const assignelt) (boost::fusion::vector2<const double&, const double&>)' note: candidates are: void assignelt::operator()(Pair&) const [with Pair = boost::fusion::vector2<const double&, const double&>] I don't understand why this error happens. The operator() is const as it should be. The template argument matches. I've tried with operator()( const Pair& ) as well, same error. #include <iostream> #include <typeinfo> #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/at_c.hpp> #include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/for_each.hpp> #include <boost/fusion/include/begin.hpp> #include <boost/fusion/include/end.hpp> #include <boost/fusion/include/next.hpp> #include <boost/fusion/include/deref.hpp> #include <boost/fusion/include/zip.hpp> #include <boost/utility/enable_if.hpp> #include <boost/fusion/include/is_sequence.hpp> using namespace boost::fusion; struct params { double field1; double field2; double field3; unsigned int field4; unsigned int field5; unsigned int field6; unsigned int field7; params() {} template <typename Seq> params(const Seq& seq, typename boost::enable_if< boost::fusion::traits::is_sequence<Seq> >::type* = 0); }; BOOST_FUSION_ADAPT_STRUCT( params, (double, field1) (double, field2) (double, field3) (unsigned int, field4) (unsigned int, field5) (unsigned int, field6) (unsigned int, field7) ) struct assignelt { template <typename Pair> void operator()( Pair& rhs ) const { at_c<0,Pair>(rhs) = at_c<1,Pair>(rhs); } }; template <typename Seq> params::params(const Seq& seq, typename boost::enable_if< boost::fusion::traits::is_sequence<Seq> >::type*) { for_each(zip(*this, seq), assignelt()); } struct printtype { template <typename T> void operator()( const T& rhs) const { std::cout<< rhs <<std::endl; } }; int main() { typedef vector<double,double,double,unsigned int,unsigned int,unsigned int,unsigned int> vec_type; const vec_type v(4.5, 5.5, 5.4, 1,2,3,4); params p; boost::fusion::for_each( p, printtype() ); std::cout<<"----------------------------------"<<std::endl; params pp(v); boost::fusion::for_each( pp, printtype() ); } rds,
participants (3)
-
Hartmut Kaiser
-
Hicham Mouline
-
Joel de Guzman