views:

50

answers:

2

For a little library project I'm using boost::tuple. Right now, I'm facing the problem of turning a "cons list" I operated on via metaprogramming back to a boost::tuple<...> type. The "dirty" solution would be to provide lots of partial specialications a la

template<class T> struct id{typedef T type;};

template<class TL> struct type_list_to_tuple_type;

template<class T1>
struct type_list_to_tuple_type<
    boost::tuples::cons<T1,boost::tuples::null_type>
> : id<boost::tuple<T1> > {}

template<class T1, class T2>
struct type_list_to_tuple_type<
    boost::tuples::cons<T1,
    boost::tuples::cons<T2,boost::tuples::null_type> >
> : id<boost::tuple<T1,T2> > {}

template<class T1, class T2, class T3>
struct type_list_to_tuple_type<
    boost::tuples::cons<T1,
    boost::tuples::cons<T2,
    boost::tuples::cons<T3,boost::tuples::null_type> > >
> : id<boost::tuple<T1,T2,T3> > {}

...

But this is tedious and error-prone, especially because I need support for tuples with possibly many elements. These tuple types are automatically generated via operator overloading. If possible, I'd like to avoid having to write so many specializations.

Any idea on how to do that without any C++0x features? I suppose it's not possible. But maybe I'm overlooking something.

Edit: I actually tried this with the experimental C++0x support only to find out that it doesn't yet work:

template<class TPH>
class type_pack_holder_to_tuple_type;

template<class...Types>
class type_pack_holder_to_tuple_type<
        type_pack_holder<Types...> >
: id< boost::tuple<Types...> > {};

G++ 4.5.1 says:

sorry, unimplemented: cannot expand 'Types ...' into
a fixed-length argument list

:-(

A: 

Clearly, the answer to your question is linked to Boost.Preprocessor. Enumeration of template parameters is kind of its specialty !

Have a look at BOOST_PP_LOCAL_ITERATE, BOOST_PP_ENUM_PARAMS and BOOST_PP_N_PARAMS. They're the key.

BOOST_PP_REPEAT and BOOST_PP_COMMA_IF might be of some help as well.

Benoît
+3  A: 

If you're doing template metaprogramming and you need conversion from typelists to tuple, maybe you should consider using Boost.MPL and Boost.Fusion. The former provides a set of compile-time containers and algorithms to manipulate list of times, and the latter make the link between pure compile-time (MPL) and pure runtime (STL) by providing "hybrid" containers and algorithms, that can be operated on either at compile-time through template metaprogramming, or at runtime as tuples.

However, to answer your question, I don't think you need to transform your cons list into a tuple since the tuple class is only a convenience to declare tuple more easily. In fact, tuple simply inherits from its corresponding cons list, e.g. tuple<int, float> inherits from cons<int, cons<float, null_type> > without adding any member data or functions. So basically, when you declare a tuple, the library "creates" the corresponding cons list; since you already creates your own cons list, you don't need the tuple class anymore.

Luc Touraille
I'm just gonna go use cons directly, thanks!
sellibitze