
I have a list of fundamental types (known at compile time). For each of these types I want to declare a templated member in a class. So, instead of class foo { private: int int_variable; double double_variable; ... /* rest of types */ }; I want something like class foo { private: variable_list<int, double, ... /* rest of types */> variable; }; and then access "foo::variable" with a template-like syntax. E.g. "variable.get<int>()". Does anyone have any idea how I can accomplish this? -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

Ares Lagae wrote:
I have a list of fundamental types (known at compile time). For each of these types I want to declare a templated member in a class.
So, instead of
class foo { private: int int_variable; double double_variable; ... /* rest of types */ };
I want something like
class foo { private: variable_list<int, double, ... /* rest of types */> variable; };
and then access "foo::variable" with a template-like syntax. E.g. "variable.get<int>()".
Does anyone have any idea how I can accomplish this?
Hi, you could try: Boost.Fusion (only in CVS) or Boost.Tuple (http://boost.org/libs/tuple/doc/tuple_users_guide.html). -- HTH, dave

David Klein wrote:
Boost.Tuple (http://boost.org/libs/tuple/doc/tuple_users_guide.html).
Boost.Tuple is close to what I want. However, I want to access based on type rather than index. E.g. I when I have a typelist typedef boost::mpl::vector<int, float> I want to generate a kind of tuple from the typelist that contains variables that can be accessed using tuple.get<int>() and tuple.get<float>(). (Note that I do not want a union.) I also need the ability to, given two typelists typedef boost::mpl::vector<int, long> types; typedef boost::mpl::vector<float, double> types; want to declare member variables with type e.g. "std::pair<int, float>", "std::pair<int, double>", "std::pair<long, float>", "std::pair<long, double>".
Boost.Fusion (only in CVS)
I will have a look at the Fusion library. -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

Boost::variant if you want your variable to hold just one of the types, and hopefully you know what type is holds. You have to use a variant visitor to access it if you don't. Attempts to use get<int> when the type isn't castable to it will throw an exception. Ares Lagae wrote:
I have a list of fundamental types (known at compile time). For each of these types I want to declare a templated member in a class.
So, instead of
class foo { private: int int_variable; double double_variable; ... /* rest of types */ };
I want something like
class foo { private: variable_list<int, double, ... /* rest of types */> variable; };
and then access "foo::variable" with a template-like syntax. E.g. "variable.get<int>()".
Does anyone have any idea how I can accomplish this?

Jeffrey Holle wrote:
Boost::variant if you want your variable to hold just one of the types, and hopefully you know what type is holds. You have to use a variant visitor to access it if you don't. Attempts to use get<int> when the type isn't castable to it will throw an exception.
Union-like containers are not suited, because I want a variable for _each_ of the types. See my other post about boost::fusion::map. -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

Ares Lagae ha escrito:
Jeffrey Holle wrote:
Boost::variant if you want your variable to hold just one of the types, and hopefully you know what type is holds. You have to use a variant visitor to access it if you don't. Attempts to use get<int> when the type isn't castable to it will throw an exception.
Union-like containers are not suited, because I want a variable for _each_ of the types. See my other post about boost::fusion::map.
I guess fusion can be used to implement what you want, but MPL probably also suffices. Please see the attached file, is this kind of what you're after? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Joaquín, Mª López Muñoz wrote:
I guess fusion can be used to implement what you want, but MPL probably also suffices. Please see the attached file, is this kind of what you're after?
Joaquín, Thank you very much! This is (almost) exactly what I want. I have a couple of questions though. 1/ Consider typedef variable_list_seq<boost::mpl::vector<int, char, double> > vl_type; Instead of having, for each type in the typelist, a variable of that type, I need a variable depending on that type. This can easily be accomplished by changing variable_list_member to hold my_type<T> rather than T. I was wondering, however, if variable_list_member can be eliminated, and my_type passed as a template argument. E.g. suppose I write a metafunction template <typename T> struct my_type { typedef /* some type */ type; } to somehow declare typedef variable_list_seq<boost::mpl::vector<int, char, double>, my_type> vl_type; to obtain a variable list with "keys" int, char, double and variables of type my_type<int>::type, .... 2/ would it be possible to generated variables my_type<T1, T2> for all possible combinations of T1 and T2, where T1 and T2 are types in two typelists? Something like typedef product_variable_list_seq<boost::mpl::vector<...>, boost::mpl::vector<...>, my_type> vl_type; where my_type is a template <typename T1, typename T2> struct my_type { typedef /* some type */ type; } Best regards, -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

Ares Lagae ha escrito: [...]
I was wondering, however, if variable_list_member can be eliminated, and my_type passed as a template argument. E.g. suppose I write a metafunction
template <typename T> struct my_type { typedef /* some type */ type; }
to somehow declare
typedef variable_list_seq<boost::mpl::vector<int, char, double>, my_type> vl_type;
to obtain a variable list with "keys" int, char, double and variables of type my_type<int>::type, ....
Yep, this can be done adding an optional template parameter to variable_list_seq, as shown in the example attached. Note that variable_list_member is not elminated, but merely supplemented with your my_type metafunction so as to be able to customize member types.
2/ would it be possible to generated variables my_type<T1, T2> for all possible combinations of T1 and T2, where T1 and T2 are types in two typelists?
Something like
typedef product_variable_list_seq<boost::mpl::vector<...>, boost::mpl::vector<...>, my_type> vl_type;
where my_type is a
template <typename T1, typename T2> struct my_type { typedef /* some type */ type; }
Again, starting from the simpler variable_list_seq one can write a new product_variable_list_seq working on the cartesian product of two MPL sequences: template<typename T> struct pair_with:boost::mpl::pair<T,boost::mpl::_>{}; template<typename Sequence1,typename Sequence2> struct sequence_product: boost::mpl::fold< Sequence1, boost::mpl::vector0<>, boost::mpl::joint_view< boost::mpl::_1, boost::mpl::transform< Sequence2, pair_with<boost::mpl::_2> > >
{}; The file attached also exercises a possible implementation. Things are a little more complex now, I strongly suspect this kind of stuff can be more easily done with fusion, but alas I haven't had time to learn about that lib. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Thanks, This is how I thought it could be done, but I don't have enough experience with the Boost::MPL library yet to actually code it and get it compiled without errors :-) I have the template metaprogramming book at home. That should help me to understand the code in detail. Best regards, -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/

I thing the first problem can be solved using Boost.Fusion: // the names of the types in the application typedef char int8; typedef short int16; typedef int int32; typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; typedef float float32; typedef double float64; // an mpl vector containing all the types typedef boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64> types; // a typedef of a fusion map with a variable for each type typedef boost::fusion::map< boost::fusion::pair<int8, my_type_depending_on<int8> > boost::fusion::pair<int16, my_type_depending_on<int16> > boost::fusion::pair<int32, my_type_depending_on<int32> > boost::fusion::pair<uint8, my_type_depending_on<uint8> > boost::fusion::pair<uint16, my_type_depending_on<uint16> > boost::fusion::pair<uint32, my_type_depending_on<uint32> > boost::fusion::pair<float32, my_type_depending_on<float32> > boost::fusion::pair<float64, my_type_depending_on<float64> >
map_type;
// the variables map_type variables; // use a variable at<int8>(variables) However, there is a lot of redundancy in the boost::fusion::map typedef. Is there any way to obtain the boost::fusion::map typedef automatically from the boost::mpl::vector? I have the following related problem. // an mpl vector containing all the size types typedef boost::mpl::vector<uint8, uint16, uint32> size_types; // an mpl vector containing all the scalar types typedef boost::mpl::vector<int8, int16, int32, uint8, uint16, uint32, float32, float64> scalar_types; now i need a variable for each combination of size_types and scalar types. Something like typedef boost::fusion::map< boost::fusion::pair<uint8, int8, my_type_depending_on<uint8, int8> > boost::fusion::pair<uint8, int16, my_type_depending_on<uint8, int16> > boost::fusion::pair<uint8, int32, my_type_depending_on<uint8, int32> > boost::fusion::pair<uint8, uint8, my_type_depending_on<uint8, uint8> > boost::fusion::pair<uint8, uint16, my_type_depending_on<uint8, uint16> > boost::fusion::pair<uint8, uint32, my_type_depending_on<uint8, uint32> > boost::fusion::pair<uint8, float32, my_type_depending_on<uint8, float32> > boost::fusion::pair<uint8, float64, my_type_depending_on<uint8, float64> > boost::fusion::pair<uint16, int8, my_type_depending_on<uint16, int8> > boost::fusion::pair<uint16, int16, my_type_depending_on<uint16, int16> > boost::fusion::pair<uint16, int32, my_type_depending_on<uint16, int32> > boost::fusion::pair<uint16, uint8, my_type_depending_on<uint16, uint8> > boost::fusion::pair<uint16, uint16, my_type_depending_on<uint16, uint16> > boost::fusion::pair<uint16, uint32, my_type_depending_on<uint16, uint32> > boost::fusion::pair<uint16, float32, my_type_depending_on<uint16, float32>
boost::fusion::pair<uint16, float64, my_type_depending_on<uint16, float64> boost::fusion::pair<uint32, int8, my_type_depending_on<uint32, int8> > boost::fusion::pair<uint32, int16, my_type_depending_on<uint32, int16> > boost::fusion::pair<uint32, int32, my_type_depending_on<uint32, int32> > boost::fusion::pair<uint32, uint8, my_type_depending_on<uint32, uint8> > boost::fusion::pair<uint32, uint16, my_type_depending_on<uint32, uint16> > boost::fusion::pair<uint32, uint32, my_type_depending_on<uint32, uint32> > boost::fusion::pair<uint32, float32, my_type_depending_on<uint32, float32>
boost::fusion::pair<uint32, float64, my_type_depending_on<uint32, float64>
map_type;
Again, I want to obtain the boost::fusion::map typedef automatically from the two boost::mpl::vectors. -- Ares Lagae Computer Graphics Research Group, Katholieke Universiteit Leuven http://www.cs.kuleuven.be/~ares/
participants (4)
-
Ares Lagae
-
David Klein
-
Jeffrey Holle
-
Joaquín Mª López Muñoz