Boost logo

Boost :

From: Giovanni P. Deretta (lordshoo_at_[hidden])
Date: 2005-04-26 04:18:40


Hi,

I have been using a small extension to the tuple library 'get' function,
that I have found very handy. It allows the extraction of an element of
a tuple by specifying its type instead of the index.
Example:

        given the tuple boost::tuple<type1, type2, type3>

        get<type1> returns the first element of the tuple of that type.

This allows one to write more self describing code: you don't need to
look up the tuple element type when you find an indexed get function
buried deep inside some code.
This is especially useful with nested tuples where for example
'get<3>(get<5>(get<0>(my_tuple)))' looks more like line noise than real
code :).

I use type wrappers to wrap built-in types and give them unique names (a
typedef that creates unique objects instead of aliases would be really
useful here!).

Anyway, here is my code. It is really a quick hack, i probably did get
returns type wrong (probably works only for value type elements), and
I'm sure metaprogramming experts here can do much better.

   namespace detail {
     namespace mpl = boost::mpl;

     template <typename Tuple, typename Type, int Index>
     struct traverse {
       typedef typename ::boost::tuples::element<Index, Tuple>::type
this_type;
       typedef typename mpl::if_
       <boost::is_same
       <this_type, Type>,
        mpl::int_<Index>,
        typename traverse<Tuple, Type, Index-1>::type
>::type type;
     };

     template<typename Tuple, typename Type>
     struct traverse <Tuple, Type, -1> {
       typedef boost::mpl::int_
       <boost::tuples::length<Tuple>::value> type;
     };

     template <typename Tuple, typename Type>
     class index_of_type {

     public:
       typedef typename
       traverse<Tuple,
                Type,
                boost::tuples::length<Tuple>::value-1>::type type;
     };
   }

   template <typename Type, typename Tuple>
   Type& get(Tuple& tp) {
     typedef typename detail::index_of_type<Tuple, Type>::type index;
     return boost::tuples::get<index::value>(tp);
   }

   template <typename Type, typename Tuple>
   const Type& get(const Tuple& tp) {
     typedef typename detail::index_of_type<Tuple, Type>::type index;
     return boost::tuples::get<index::value>(tp);
   }
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk