c++ - Combination of types using boost::mpl -
i have list of types, want construct list of combinations 2 elements. example:
namespace mpl = boost::mpl; typedef mpl::vector<int, long> typelist; // mpl magic... // wanted list equivalent to: typedef mpl::vector<pair<int, int>, pair<int, long>, pair<long, int>, pair<long, long> > combinations;
here, pair<t1,t2>
std::pair<t1,t2>
, or mpl::vector<t1,t2>
. how this? interested in removing duplicates when consider pair<t1, t2> == pair<t2, t1>
.
thanks.
the list of combinations of single type int
list of types mpl::vector<int, long>
can computed invoking mpl::fold
:
typedef fold< mpl::vector<int, long>, vector<>, push_back<mpl::_1, std::pair<int, mpl::_2> > >::type list_of_pairs;
now, if wrap separate meta-function , invoke types of initial typelist get:
typedef mpl::vector<int, long> typelist; template <typename t, typename result> struct list_of_pairs : mpl::fold<typelist, result, mpl::push_back<mpl::_1, std::pair<t, mpl::_2> > > {}; typedef mpl::fold< typelist, mpl::vector<>, mpl::lambda<list_of_pairs<mpl::_2, mpl::_1> > >::type result_type; boost_mpl_assert( mpl::equal<result_type, mpl::vector4< std::pair<int, int>, std::pair<int,long>, std::pair<long,int>, std::pair<long,long> > >::value);
edit: answering second question:
making result containing unique elements (in sense mentioned) bit more involved. first need define meta function comparing 2 elements , returning mpl::true_/mpl::false_:
template <typename p1, typename p2> struct pairs_are_equal : mpl::or_< mpl::and_< is_same<typename p1::first_type, typename p2::first_type>, is_same<typename p1::second_type, typename p2::second_type> >, mpl::and_< is_same<typename p1::first_type, typename p2::second_type>, is_same<typename p1::second_type, typename p2::first_type> > > {};
then need define meta-function tries find given element in given list:
template <typename list, typename t> struct list_doesnt_have_element : is_same< typename mpl::find_if<list, pairs_are_equal<mpl::_1, t> >::type, typename mpl::end<list>::type> {};
now, can utilized build new list, making sure no duplicates inserted:
typedef mpl::fold< result_type, mpl::vector<>, mpl::if_< mpl::lambda<list_doesnt_have_element<mpl::_1, mpl::_2> >, mpl::push_back<mpl::_1, mpl::_2>, mpl::_1> >::type unique_result_type;
all top of head, may need tweaking here or there. idea should correct.
edit: minor corrections outlined @rafak
Comments
Post a Comment