c++ - How to use std::tuple types with boost::mpl algorithms? -
the boost::mpl
algorithms seem not able work on std::tuple
types out of box, e.g., following not compile (boost-1.46.0, g++ snapshot 2011-02-19):
#include <tuple> #include <boost/mpl/vector.hpp> #include <boost/mpl/contains.hpp> namespace mpl=boost::mpl; typedef mpl::vector<int,float,bool> types; static_assert(mpl::contains<types, float>::value, "vector contains bool"); typedef std::tuple<int,float,bool> types2; // following not compile: // error: no class template named ‘apply’ in ‘struct boost::mpl::contains_impl<boost::mpl::non_sequence_tag>’ static_assert(mpl::contains<types2, float>::value, "tuple contains bool");
what easiest way make boost::mpl
algorithms work on std::tuple
?
- does evtl.
boost::fusion
provide functionality (asboost::tuple
)? - if not, possible carry on fusion implementation
boost::tuple
std::tuple
easily? - if not either, have implement all intrinsic metafunctions listed in mpl documentation or ones sufficient? (the docs says "many of intrinsic metafunctions offer default implementation work in majority of cases", not clear ones exactly. , tests providing begin , end did not lead me anywhere).
converting std::tuple boost types , seems easiest way
#include <iostream> #include <tuple> #include <type_traits> #include <boost/mpl/if.hpp> #include <boost/mpl/not.hpp> #include <boost/mpl/vector.hpp> namespace mpl = boost::mpl; template<typename sequence, typename t> struct push_front; template<template<typename...> class sequence, typename t, typename ... args> struct push_front< sequence<args...>,t> { typedef sequence<t, args...> type; }; template<template<typename...> class to, typename from> struct tuple_change; template<template<typename...> class to, template<typename...> class from, typename ... args> struct tuple_change<to, from<args...>> { typedef to<args...> type; }; template<typename sequence, size_t n> struct @ : std::tuple_element<n,sequence> { }; template<typename sequence> struct empty; template<template<typename...> class sequence, typename ... args> struct empty<sequence<args...>> { typedef sequence<> type; }; template< size_t n, typename sequence, template<typename> class pred, typename ... args > struct while_impl { typedef typename mpl::if_c< pred< typename at<sequence, sizeof...(args) - n -1>::type >::value, typename push_front< typename while_impl<n-1, sequence, pred, args...>::type, typename at<sequence,sizeof...(args)-n-1>::type >::type, typename empty< sequence > ::type >::type type; }; template< typename sequence, template<typename> class pred, typename ... args > struct while_impl<-1, sequence, pred, args...> : empty<sequence> { }; template< typename sequence, template<typename> class pred> struct while_; template< template<typename...> class sequence, template<typename> class pred, typename ... args > struct while_< sequence<args...>, pred > { typedef typename while_impl<sizeof...(args)-1, sequence<args...>, pred, args...>::type type; }; template<typename t> struct not_na : mpl::not_< std::is_same<mpl_::na, t> > { }; template<template<typename...> class to, typename from> struct to_boost; template<template<typename...> class to, typename...args > struct to_boost<to, std::tuple<args...> > : tuple_change< mpl::vector, std::tuple<args...> > { }; template< typename > struct to_std; template<template<typename...> class from, typename...args > struct to_std< from<args...> > : while_<typename tuple_change< std::tuple, from<args...> >::type, not_na> { }; static_assert( std::is_same< mpl::vector< char, int, bool>, typename to_boost<mpl::vector, std::tuple<char, int, bool> >::type >::value, "tuple_change boost failed"); static_assert( std::is_same< std::tuple< char, int, bool>, typename to_std< mpl::vector<char, int, bool> >::type >::value, "tuple_change boost failed"); int main(){ return 0;}
*tested with:
boost_1_46_0 , g++-4.5 on macosx
boost_1_45_0 , g++-4.5 on ubuntu 10.10
Comments
Post a Comment