I've got the following code that combines two vectors of arbitrary types into a combinatorial, i.e. std::vector<std::tuple<A, B>>
.
template<class A, class B>
std::vector<std::tuple<A, B>> combine(const std::vector<A>& a, const std::vector<B>& b) {
const auto combine_parts_ = [](const A& x, const B& y) {
auto result = std::tuple_cat(std::make_tuple(x), std::make_tuple(y));
return result;
};
std::vector<std::tuple<A, B>> results;
for (const auto& x : a) {
for (const auto& y : b) {
results.push_back(combine_parts_(x, y));
}
}
return results;
}
However, I'm unclear how to extend that to an arbitrary number of types/vectors. I don't care about duplicate types; in fact there may be two or more sets of the same type involved. That's okay.
Some example use cases, for instance:
const auto combinations = combine(
std::vector<int>({1,2,3})
, std::vector<int>({1,2,3})
);
const auto combinations2 = combine(
std::vector<int>({1,2,3})
, std::vector<int>({1,2,3})
, std::vector<bool>({true,false})
);
const auto combinations3 = combine(
std::vector<int>({1,2,3})
, std::vector<int>({1,2,3})
, std::vector<bool>({true,false})
, std::vector<char>({'a','b','c','d','e'})
);
Chiefly, what I want to do is avoid the ugly nested for loop. At the same time, I want to combine some unit testing combinatorial use cases in order to work with the resulting std::tuple<...>
as the test case.
Note, I am not talking about permutations of a homogeneous set here. That's been a point of confusion from prior questions.
I think it might have something to do with templates, variadics, std::tuple_cat
, somewhere along the way, but I don't know.
Thoughts? Suggestions?
std::array
support is a bit lacking. Still, I think the fundamentals are there. – Cathrine