[tuple] How to manipulate the types
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? example given the type T and tuple<int, float>, obtain a tuple<T, int, float> Thanks in advance, Adrián
Adrián Etchevarne ha escrito:
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?
example given the type T and tuple<int, float>, obtain a tuple<T, int, float>
Thanks in advance, Adrián
Hi Adrián, I think you've got to resort to brute force, although Boost.PP helps a lot with this kind of tasks. Please find attached a possible implementation of a tuple_from_cons helper metafunction, though I'm sure the PP experts out there could come out with simpler and nicer formulations. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo ___________________________________________________________________________ Antes de imprimir este mensaje, asegúrese de que es necesario. La mejora del medio ambiente empieza en nuestro día a día. ___________________________________________________________________________
Adrián Etchevarne <adrian.etchevarne@gmail.com> writes:
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?
example
given the type T and tuple<int, float>, obtain a tuple<T, int, float>
That's a lot easier to solve, in some sense, than the "Problem:" above. The cons list *is* a valid tuple. So to inserta new type at the front, just write const<T, the-shorter-cons-list> You might also want to look at http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/index.h... which was recently accepted into Boost. -- Dave Abrahams Boost Consulting www.boost-consulting.com
David Abrahams wrote:
You might also want to look at
http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/index.h...
which was recently accepted into Boost.
Has the final decision been announced somewhere? João
João Abecasis wrote:
David Abrahams wrote:
You might also want to look at
http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/index.h...
which was recently accepted into Boost.
Has the final decision been announced somewhere?
AFAIK, not yet. I think Ronald Garcia is in vacation somehere :) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
David Abrahams wrote:
That's a lot easier to solve, in some sense, than the "Problem:"
above. The cons list *is* a valid tuple. So to inserta new type at
the front, just write
const<T, the-shorter-cons-list>
Thanks to David and Joaquín for their response. tuple inherit from cons, so tuple is a cons. cons<> has an implicit conversion to tuple, but the types are not the same (or I am missing something): template< typename Cons, typename T> struct p_front { typedef cons<T, Cons> type; }; typedef p_front< tuple<int>::inherited, float>::type pushed; (is_same< pushed, tuple<float, int> >::value == false) // Not the same If I declare pushed value; value has cons operations, not tuple operations. The implicit conversion mitigates this. How I can sinthesize a tuple type? Joaquín's brute force approach is the ultimate solution?
You might also want to look at
http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/index.h...
which was recently accepted into Boost.
I will read it, thanks. It looks great! Thanks, Adrián
David Abrahams wrote:
That's a lot easier to solve, in some sense, than the "Problem:"
above. The cons list is a valid tuple. So to inserta new type at
the front, just write
const<T, the-shorter-cons-list>
Thanks to all for your responses. tuple inherit from cons, so tuple is a cons. cons<> has an implicit conversion to tuple, but the types are not the same (or I am missing something): template< typename Cons, typename T> struct p_front { typedef cons<T, Cons> type; }; typedef p_front< tuple<int>::inherited, float>::type pushed; (is_same< pushed, tuple<float, int> >::value == false) // Not the same If I declare pushed value; value has cons operations, not tuple operations. The implicit conversion mitigates this. How I can sinthesize a tuple type? Joaquín's brute force approach is the ultimate solution?
You might also want to look at
http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/index.h...
which was recently accepted into Boost.
I will read it, thanks. It looks great! Thanks, Adrián
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 }}
participants (7)
-
Adrián Etchevarne
-
Adrián Etchevarne
-
Alan M. Carroll
-
David Abrahams
-
Joaquín Mª López Muñoz
-
Joel de Guzman
-
João Abecasis