If you want to not convert std :: tuple to mpl type, you can overload sending the boost tag. mpl uses:
#include <tuple> #include <boost/mpl/sequence_tag.hpp> #include <boost/mpl/pop_front_fwd.hpp> #include <boost/mpl/push_front_fwd.hpp> #include <boost/mpl/push_back_fwd.hpp> #include <boost/mpl/front_fwd.hpp> #include <boost/mpl/empty_fwd.hpp> #include <boost/mpl/size_fwd.hpp> #include <boost/mpl/at_fwd.hpp> #include <boost/mpl/back_fwd.hpp> #include <boost/mpl/clear_fwd.hpp> #include <boost/mpl/pop_back_fwd.hpp> #include <boost/mpl/iterator_tags.hpp> #include <boost/mpl/next_prior.hpp> #include <boost/mpl/deref.hpp> #include <boost/mpl/begin_end_fwd.hpp> namespace boost { namespace mpl { namespace aux { struct std_tuple; } template<class ... Args> struct sequence_tag<std::tuple<Args...> > { typedef aux::std_tuple type; }; template<> struct front_impl< aux::std_tuple > { template< typename Tuple > struct apply : std::tuple_element<0, Tuple> { }; }; template<> struct empty_impl< aux::std_tuple > { template< typename Tuple > struct apply : std::integral_constant<bool, std::tuple_size<Tuple>::value == 0> { }; }; template<> struct pop_front_impl< aux::std_tuple > { template< typename Tuple > struct apply; template< class First, class ... Types > struct apply<std::tuple<First, Types...>> { typedef std::tuple<Types...> type; }; }; template<> struct push_front_impl< aux::std_tuple > { template< typename Tuple, typename T > struct apply; template< typename T, typename ... Args > struct apply<std::tuple<Args...>, T> { typedef std::tuple<T, Args...> type; }; }; template<> struct push_back_impl< aux::std_tuple > { template< typename Tuple, typename T > struct apply; template< typename T, typename ... Args > struct apply<std::tuple<Args...>, T> { typedef std::tuple<Args..., T> type; }; }; template<> struct size_impl< aux::std_tuple > { template< typename Tuple > struct apply : std::tuple_size<Tuple> { }; }; template<> struct at_impl< aux::std_tuple > { template< typename Tuple, typename N > struct apply : std::tuple_element<N::value, Tuple> { }; }; template<> struct back_impl< aux::std_tuple > { template< typename Tuple > struct apply : std::tuple_element<std::tuple_size<Tuple>::value - 1, Tuple> { }; }; template<> struct clear_impl< aux::std_tuple > { template< typename Tuple > struct apply { typedef std::tuple<> type; }; }; template<> struct pop_back_impl< aux::std_tuple > { template<int ...> struct tuple_seq {}; template<int N, int ...S> struct tuple_gens : tuple_gens<N-1, N-1, S...> {}; template<int ...S> struct tuple_gens<0, S...>{ typedef tuple_seq<S...> type; }; template < class Tuple, class Index> struct apply_impl; template < class Tuple, int ... S> struct apply_impl<Tuple, tuple_seq<S...>> { typedef std::tuple<typename std::tuple_element<S, Tuple>::type...> type; }; template< typename Tuple > struct apply : apply_impl<Tuple, typename tuple_gens<std::tuple_size<Tuple>::value - 1>::type> { }; }; template< class ... Args > struct tuple_iter; template< class ... Args > struct tuple_iter<std::tuple<Args...>> { typedef aux::std_tuple tag; typedef forward_iterator_tag category; }; template<> struct begin_impl< aux::std_tuple > { template< class Tuple > struct apply { typedef tuple_iter<Tuple> type; }; }; template<> struct end_impl< aux::std_tuple > { template< typename > struct apply { typedef tuple_iter<std::tuple<>> type; }; }; template< typename First, class ... Args > struct deref< tuple_iter<std::tuple<First, Args...> > > { typedef First type; }; template< typename First, class ... Args > struct next< tuple_iter<std::tuple<First, Args...>> > { typedef tuple_iter< std::tuple<Args...> > type; }; } }
And related test:
#include <boost/mpl/pop_front.hpp> #include <boost/mpl/push_front.hpp> #include <boost/mpl/push_back.hpp> #include <boost/mpl/front.hpp> #include <boost/mpl/empty.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/back.hpp> #include <boost/mpl/clear.hpp> #include <boost/mpl/pop_back.hpp> #include <boost/mpl/contains.hpp> #include <boost/mpl/aux_/test.hpp> MPL_TEST_CASE() { typedef std::tuple<int, char, bool> Tuple; MPL_ASSERT((is_same<front<Tuple>::type, int>)); MPL_ASSERT_RELATION( size<Tuple>::type::value, ==, 3 ); MPL_ASSERT(( is_same< pop_front<Tuple>::type, std::tuple<char, bool> > )); MPL_ASSERT(( is_same< push_front<Tuple, unsigned>::type, std::tuple<unsigned, int, char, bool> > )); MPL_ASSERT(( is_same< push_back<Tuple, unsigned>::type, std::tuple<int, char, bool, unsigned> > )); MPL_ASSERT_RELATION( empty<Tuple>::type::value, ==, false ); MPL_ASSERT(( is_same< at_c<Tuple, 0>::type, int > )); MPL_ASSERT(( is_same< at_c<Tuple, 1>::type, char > )); MPL_ASSERT(( is_same< back<Tuple>::type, bool > )); MPL_ASSERT(( is_same< clear<Tuple>::type, std::tuple<> > )); MPL_ASSERT(( is_same< pop_back<Tuple>::type, std::tuple<int, char> > )); MPL_ASSERT(( contains<Tuple, int> )); MPL_ASSERT(( contains<Tuple, char> )); MPL_ASSERT(( contains<Tuple, bool> )); MPL_ASSERT_NOT(( contains<Tuple, unsigned> )); }
I tested this with gcc 4.7.2 and clang 3.2. It should contain everything you need to use anything in mpl (actually it is more than necessary). You can think of the tuple as mpl :: list (an iterator forward compilation type). Therefore, to make it play well, you need to implement what boost :: mpl :: list does. A quick search in the boost / mpl / list / aux_ directory: begin_end.hpp empty.hpp iterator.hpp pop_front.hpp push_back.hpp size.hpp clear.hpp front.hpp push_front.hpp tag.hpp are the relevant files that you need to implement.