Boost logo

Boost Users :

Subject: Re: [Boost-users] generate structs with all combinations of members from a given struct
From: Larry Evans (cppljevans_at_[hidden])
Date: 2010-01-31 09:12:30


On 01/31/10 07:20, Hicham Mouline wrote:
[snip]

>> Step1:
>> Create cross-product of void and {field1,field2,...}.
>> This will produce a sequence of pairs:
>>
>> no_yes =
>> ( (void,field1)
>> , (void,field2)
>> ...
>> , (void,fieldn)
>> )
>>
>> Step2:
>>
>> Create the crosss product of all rows in no_yes.
>>
>> cross_no_yes =
>> ( (void,void,..void)
>> , (field1,void,...void)
>> , (void,field2,void...,void)
>> ...
>> , (field1,field2,...fieldn)
>> )
>>
>> step3:
>>
>> remove all the voids in all the rows of cross_no_yes.
>>
>> Since the size<no_yes> == n and each element in that row is size 2,
>> the cross_no_yes size would be 2^n. Then simply rm the all void row.
>>
>> Not tested.
[snip]

My previous attachment could be simplified by using:

   template
   < typename Domains
>
struct cross_product_fold
: fold
   < Domains
   , cross_prod_nil
   , cross_product<arg<1>, arg<2> >
>
{
};
     typedef
   cross_product_fold
   < package<absent_t,fields_t>
>::type
absent_fields_seq
;
     typedef
   cross_product_fold
   < absent_fields_seq
>::type
select_fields_seq
;
> I will try this thanks very much.
>
> I will make all these types derived from a base struct with a virtual dtor.
> Then I will move this base type around various translation units (so they
> only need to know about the base struct), and then the last translation
> unit
> will have access to the same list of types and then dynamic cast the base
> struct to each of these generated structs and work with the actual type.
>
> I thought of generation a fusion vector as well but the resulting vector
> would look like this:
>
> vector<
> vector<double>,
> vector<double>,
> vector<double>,
> vector<double>,
> vector<double,double>,
> ...
>>
>
> Because all the members of params are double, there is no way to
> differentiate between different the 1st and 2nd vector<double>

Yes; however, Couldn't you, pair each type with it's index?
IOW, you have, instead of:

       typedef
     package_c<int,9001,9002,9003>::pkg_type
   fields_t
   ;

from my earlier attachment, you have:

     enum
   field_names
   { field_1
   , field_2
   ...
   , field_n
   };
       typedef
     package
     < pair<integral_c<field_names,field_1>, vector<double> >
     , pair<integral_c<field_names,field_2>, vector<double> >
     ...
     , pair<integral_c<field_names,field_I>, vector<double,double> >
     ...
>
   fields_t
   ;

Then, the resulting cross_product would be a sequence of pairs
from which you could generate a fusion map.
>
> while with PP, I could name the types params_field1 and params_field2,
>

The aforementioned fusion map would have keys like
integral_c<field_names,field_I>, for I=1,N.
You could always write a short template:

   template<field_names FieldName>
     obvious_type_from_map_meta_function?
   get_field(afore_mentioned_map)
   ;

to more conveniently access the named field.

HTH.

Larry


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