I\'d like to create the cross product of a list of types using variadic templates.
Here\'s what I have so far:
#include
#include <
Really enjoyed this "homework" assignment :)
Both solutions below create a class full of type_list typedefs, along with member functions that will check to see if a given list of types exist in the class as a type_list.
The first solution creates all possible combinations of types from 1 to N types per type_list (the width parameter defines N). The second solution creates only pairs of types.
First Solution
template struct type_list { typedef type_list type; };
template struct xprod_tlist_ {};
template
struct xprod_tlist_<1, type_list, Us...> {};
template
struct xprod_tlist_, Us...>
: type_list...
, xprod_tlist_, Us...>... {};
template struct xprod_tlist
: type_list..., xprod_tlist_, Ts...>... {
template struct exists
: std::is_base_of, xprod_tlist> {};
template struct assert_exists {
static_assert(exists::value, "Type not present in list");
};
};
Usage:
typedef xprod_tlist<5, int, char, string, float, double, long> X;
//these pass
X::assert_exists assert_test1;
X::assert_exists assert_test2;
//these fail
X::assert_exists assert_test3;
X::assert_exists assert_test4;
//true
auto test1 = X::exists::value;
auto test2 = X::exists::value;
//false
auto test3 = X::exists::value;
auto test4 = X::exists::value;
Second Solution
template struct type_pair { typedef type_pair type; };
template struct type_list {};
template struct xprod_tlist_ {};
template
struct xprod_tlist_, type_list>
: type_pair..., xprod_tlist_, type_list> {};
template
struct xprod_tlist : xprod_tlist_, type_list> {
template struct exists
: std::is_base_of, xprod_tlist> {};
template struct assert_exists {
static_assert(exists::value, "Type not present in list");
};
};
Usage:
typedef xprod_tlist X;
//these pass
X::assert_exists assert_test1;
X::assert_exists assert_test2;
X::assert_exists assert_test3;
X::assert_exists assert_test4;
X::assert_exists assert_test5;
X::assert_exists assert_test6;
X::assert_exists assert_test7;
X::assert_exists assert_test8;
X::assert_exists assert_test9;
//this fails
X::assert_exists assert_test10;
//true
auto test1 = X::exists::value;
auto test2 = X::exists::value;
auto test3 = X::exists::value;
auto test4 = X::exists::value;
auto test5 = X::exists::value;
auto test6 = X::exists::value;
auto test7 = X::exists::value;
auto test8 = X::exists::value;
auto test9 = X::exists::value;
//false
auto test10 = X::exists::value;