I needed to do exactly this myself. My solution is attached. After including this header, if you have an existing tuple type T, you can do what you want with typedef boost::tuples::add_type<the_type, T>::type extended_tuple; Adrián Etchevarne wrote:
Problem: How can I get a tuple type from a tuples::cons<> list ? example: given the type: cons<int, cons<float, cons<int, null_type> > >
obtain tuple<int, float, int>
Real problem: I need to insert a type T at the beginning of a tuple, how I can do this?
# pragma once # include <boost/tuple/tuple.hpp> # include <boost/bind.hpp> # include <boost/mpl/if.hpp> /** @file This is an utility extention to Boost::Tuples. The purpose is to be able to convert an existing tuple type to another tuple type with an additional type added to the front of the list of types in the tuple. For instance, converting a tuple of the form @c tuple<A2,A1,A0> to @c tuple<A3,A2,A1,A0>: @code // T is the current tuple type tuple::<A2,A1,A0> typedef boost::tuples::add_type<A3, T>::type longer_tuple; @endcode */ namespace boost { namespace tuples { /** Metafunction to create a @c get function suitable for @c boost::bind. @a N is the element index (0 based) and @a T is the tuple type. Usage: @code typedef boost::tuple::<int, double, string> triple; // A bound function to get the string element. boost::bind(boost::tuples::get_mf<2,triple>::type, _1)); @endcode You can also use the static @c bind method to return a bound object without explicitly calling @c boost::bind. The following is exactly equivalen to the previous example. @code boost::tuples::get_mf<2,triple>::bind(); @endcode */ template < int N, typename T > struct get_mf { typedef typename boost::tuples::element<N,T>::type return_type; inline static return_type& type(T& tuple) { return tuple.get<N>(); } typedef return_type& (*function_type)(T&); /* The return type was discovered via compiler errors and is sensitive to any implementation change in Boost.bind. I'm not sure how to do this better as Boost.bind doesn't have a facility for computing this type. */ inline static boost::_bi::bind_t< return_type& , function_type , boost::_bi::list1<typename boost::_bi::list_av_1< boost::arg<1> >::B1> > bind() { return boost::bind(type, _1); } }; /** Metafunction to compute a new tuple from a type and an existing tuple. For a type @c R and a tuple <tt>tuple<T0,T1...></tt> the result is the tuple <tt>tuple<R,T0,T1,...></tt> Example: @code typedef add_type<thing_t, current_tuple_t>::type extended_tuple_t; @endcode */ template < typename R, typename T, int N = 0 > struct add_type { //! @cond NO_DOCS typedef typename add_type<R, T, length<T>::value >::type type; //! @endcond NO_DOCS }; /** Metafunction class that calls @c add_type. Example: @code typedef boost::tuple<int, char, float> tuple_t; typedef add_type_mf::apply<thing_t, tuple_t>::type extended_tuple_t; // extended_tuple_t == boost::tuple<thing_t, int, char, float> @endcode */ struct add_type_mf { //! @cond NO_DOCS template < typename TYPE, typename TUPLE > struct apply { typedef typename add_type<TYPE,TUPLE>::type type; }; //! @endcond NO_DOCS }; //! @cond NO_DOCS template < typename R, typename T > struct add_type<R,T,1> { typedef tuple<R, typename element<0, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,2> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,3> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type, typename element<2, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,4> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type, typename element<2, T>::type, typename element<3, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,5> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type, typename element<2, T>::type, typename element<3, T>::type, typename element<4, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,6> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type, typename element<2, T>::type, typename element<3, T>::type, typename element<4, T>::type, typename element<5, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,7> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type, typename element<2, T>::type, typename element<3, T>::type, typename element<4, T>::type, typename element<5, T>::type, typename element<6, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,8> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type, typename element<2, T>::type, typename element<3, T>::type, typename element<4, T>::type, typename element<5, T>::type, typename element<6, T>::type, typename element<7, T>::type > type; }; template < typename R, typename T > struct add_type<R,T,9> { typedef tuple<R, typename element<0, T>::type, typename element<1, T>::type, typename element<2, T>::type, typename element<3, T>::type, typename element<4, T>::type, typename element<5, T>::type, typename element<6, T>::type, typename element<7, T>::type, typename element<8, T>::type > type; }; //! @endcond }}