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 <
Note: This is NOT what the OP asked for... but may be of relevance to others (like me) who stumble upon this question. Here is how it can be done using a Loki::TypeList (i.e. prior C++-11), perhaps of historical interest or for compatability sake.
Also, perhaps it is presumptuous of me to pollute loki's namespace. YMMV.
crossproduct.h
#include "loki/NullType.h"
#include "loki/Typelist.h"
namespace Loki {
namespace TL {
/// a pair of two types
template
struct TypePair
{
typedef A_t A;
typedef B_t B;
};
/// a template which takes one type and pairs it with all other types
/// in another typelist
template struct DistributePair;
/// specialization of Distribute for the nulltype
template < class TList >
struct DistributePair< NullType, TList >
{
typedef NullType type;
};
/// specialization of Distribute where the second parameter is nulltype
template
struct DistributePair< T, NullType >
{
typedef NullType type;
};
/// specialization of Distribute where the first parameter is a
/// typelist
template
struct DistributePair< T, Typelist >
{
typedef Typelist<
TypePair,
typename DistributePair::type
> type;
};
/// performs cartesion product of two typelists
template struct CrossProduct;
/// specialization of CrossProduct for NullType
template
struct CrossProduct< NullType, TListB >
{
typedef NullType type;
};
/// specialization of CrossProduct for recursion
template
struct CrossProduct< Typelist, TListB >
{
typedef typename Append<
typename DistributePair< Head,TListB >::type,
typename CrossProduct< Tail, TListB >::type
>::Result type;
};
} // namespace TL
} // namespace Loki
test.cpp
#include
#include
#include
struct A{};
struct B{};
struct C{};
struct D{};
struct E{};
struct F{};
typedef LOKI_TYPELIST_3(A,B,C) TypeListA_t;
typedef LOKI_TYPELIST_3(D,E,F) TypeListB_t;
typedef typename Loki::TL::CrossProduct< TypeListA_t, TypeListB_t >::type Cross_t;
template const char* toString();
template <> const char* toString(){ return "A"; };
template <> const char* toString(){ return "B"; };
template <> const char* toString(){ return "C"; };
template <> const char* toString(){ return "D"; };
template <> const char* toString(){ return "E"; };
template <> const char* toString(){ return "F"; };
template struct Printer
{
Printer()
{
std::cout << toString() << ", ";
}
};
template
struct Printer< Loki::TL::TypePair >
{
Printer()
{
std::cout << "(" << toString() << "," << toString() << "), ";
}
};
typedef Loki::GenScatterHierarchy< TypeListA_t, Printer > PrinterA_t;
typedef Loki::GenScatterHierarchy< TypeListB_t, Printer > PrinterB_t;
typedef Loki::GenScatterHierarchy< Cross_t, Printer > PrinterCross_t;
int main(int argc, char** argv)
{
std::cout << "\nType list A: \n ";
PrinterA_t a;
std::cout << "\nType list B: \n ";
PrinterB_t b;
std::cout << "\nType list Cross: \n ";
PrinterCross_t cross;
return 0;
}
output
Type list A:
A, B, C,
Type list B:
D, E, F,
Type list Cross:
(A,D), (A,E), (A,F), (B,D), (B,E), (B,F), (C,D), (C,E), (C,F),