Boost logo

Boost Users :

Subject: Re: [Boost-users] fusion struct adapt macro, construct the struct from a fusion vector
From: Hicham Mouline (hicham_at_[hidden])
Date: 2010-01-19 04:22:13


----- Original Message -----
From: "Hartmut Kaiser" <hartmut.kaiser_at_[hidden]>
To: <boost-users_at_[hidden]>
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,


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net