#include <cstddef>
#include <utility>
#include <vector>
#include <tuple>
#include <string>
#include <iostream>
using std::size_t;
template<size_t...> struct seq {};
template<size_t Min, size_t Max, size_t... s>
struct make_seq:make_seq< Min, Max-1, Max-1, s... > {};
template<size_t Min, size_t... s>
struct make_seq< Min, Min, s... > {
typedef seq<s...> type;
};
template<size_t Max, size_t Min=0>
using MakeSeq = typename make_seq<Min, Max>::type;
size_t product_size() {
return 1;
}
template<typename... Sizes>
size_t product_size( size_t x, Sizes... tail ) {
return x * product_size(tail...);
}
namespace details {
template<typename max_iterator, typename Lambda>
void for_each_index( max_iterator mbegin, max_iterator mend, Lambda&& f, std::vector<size_t>& idx ) {
if (mbegin == mend) {
f(idx);
} else {
for (size_t i = 0; i < *mbegin; ++i) {
idx.push_back(i);
for_each_index(mbegin+1, mend, f, idx);
idx.pop_back();
}
}
}
template<typename Lambda>
void for_each_index( std::vector<size_t> const& maxes, Lambda&& f ) {
std::vector<size_t> idx;
details::for_each_index( maxes.begin(), maxes.end(), f, idx );
}
template<size_t... s, typename... Ts>
std::vector< std::tuple<Ts...> > does_it_blend( seq<s...>, std::tuple< std::vector<Ts>... >const& input ) {
std::vector< std::tuple<Ts...> > retval;
retval.reserve( product_size( std::get<s>(input).size()... ) );
std::vector<size_t> maxes = {
(std::get<s>(input).size())...
};
for_each_index( maxes, [&](std::vector<size_t> const& idx){
retval.emplace_back( std::get<s>(input)[idx[s]]... );
});
return retval;
}
}
template<typename... Ts>
std::vector< std::tuple<Ts...> > does_it_blend( std::tuple< std::vector<Ts>... >const& input ) {
return details::does_it_blend( MakeSeq< sizeof...(Ts) >(), input );
}
int main() {
std::tuple< std::vector<int>, std::vector<bool>, std::vector<std::string> > input {
{ 1, 2, 3}, { false, true}, { "Hello", "World"}
};
// should become 3 x 2 x 2 = 12 cases { {1, false, "Hello"}, ... , {3, true, "World"} }
std::vector< std::tuple<int, bool, std::string> > test_cases = does_it_blend( input );
for( auto&& x:test_cases ) {
std::cout << std::get<0>(x) << "," << std::get<1>(x) << "," << std::get<2>(x) << "\n";
}
}
CiAgICAjaW5jbHVkZSA8Y3N0ZGRlZj4KICAgICNpbmNsdWRlIDx1dGlsaXR5PgogICAgI2luY2x1ZGUgPHZlY3Rvcj4KICAgICNpbmNsdWRlIDx0dXBsZT4KICAgICNpbmNsdWRlIDxzdHJpbmc+CiAgICAjaW5jbHVkZSA8aW9zdHJlYW0+CiAgICAgCiAgICB1c2luZyBzdGQ6OnNpemVfdDsKICAgICAKICAgIHRlbXBsYXRlPHNpemVfdC4uLj4gc3RydWN0IHNlcSB7fTsKICAgIHRlbXBsYXRlPHNpemVfdCBNaW4sIHNpemVfdCBNYXgsIHNpemVfdC4uLiBzPgogICAgc3RydWN0IG1ha2Vfc2VxOm1ha2Vfc2VxPCBNaW4sIE1heC0xLCBNYXgtMSwgcy4uLiA+IHt9OwogICAgdGVtcGxhdGU8c2l6ZV90IE1pbiwgc2l6ZV90Li4uIHM+CiAgICBzdHJ1Y3QgbWFrZV9zZXE8IE1pbiwgTWluLCBzLi4uID4gewogICAgICAgIHR5cGVkZWYgc2VxPHMuLi4+IHR5cGU7CiAgICB9OwogICAgdGVtcGxhdGU8c2l6ZV90IE1heCwgc2l6ZV90IE1pbj0wPgogICAgdXNpbmcgTWFrZVNlcSA9IHR5cGVuYW1lIG1ha2Vfc2VxPE1pbiwgTWF4Pjo6dHlwZTsKICAgICAKICAgIHNpemVfdCBwcm9kdWN0X3NpemUoKSB7CiAgICAgIHJldHVybiAxOwogICAgfQogICAgdGVtcGxhdGU8dHlwZW5hbWUuLi4gU2l6ZXM+CiAgICBzaXplX3QgcHJvZHVjdF9zaXplKCBzaXplX3QgeCwgU2l6ZXMuLi4gdGFpbCApIHsKICAgICAgcmV0dXJuIHggKiBwcm9kdWN0X3NpemUodGFpbC4uLik7CiAgICB9CiAgICBuYW1lc3BhY2UgZGV0YWlscyB7CiAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIG1heF9pdGVyYXRvciwgdHlwZW5hbWUgTGFtYmRhPgogICAgICB2b2lkIGZvcl9lYWNoX2luZGV4KCBtYXhfaXRlcmF0b3IgbWJlZ2luLCBtYXhfaXRlcmF0b3IgbWVuZCwgTGFtYmRhJiYgZiwgc3RkOjp2ZWN0b3I8c2l6ZV90PiYgaWR4ICkgewogICAgICAgIGlmIChtYmVnaW4gPT0gbWVuZCkgewogICAgICAgICAgZihpZHgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8ICptYmVnaW47ICsraSkgewogICAgICAgICAgICBpZHgucHVzaF9iYWNrKGkpOwogICAgICAgICAgICBmb3JfZWFjaF9pbmRleChtYmVnaW4rMSwgbWVuZCwgZiwgaWR4KTsKICAgICAgICAgICAgaWR4LnBvcF9iYWNrKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIExhbWJkYT4KICAgICAgdm9pZCBmb3JfZWFjaF9pbmRleCggc3RkOjp2ZWN0b3I8c2l6ZV90PiBjb25zdCYgbWF4ZXMsIExhbWJkYSYmIGYgKSB7CiAgICAgICAgc3RkOjp2ZWN0b3I8c2l6ZV90PiBpZHg7CiAgICAgICAgZGV0YWlsczo6Zm9yX2VhY2hfaW5kZXgoIG1heGVzLmJlZ2luKCksIG1heGVzLmVuZCgpLCBmLCBpZHggKTsKICAgICAgfQogICAgICB0ZW1wbGF0ZTxzaXplX3QuLi4gcywgdHlwZW5hbWUuLi4gVHM+CiAgICAgIHN0ZDo6dmVjdG9yPCBzdGQ6OnR1cGxlPFRzLi4uPiA+IGRvZXNfaXRfYmxlbmQoIHNlcTxzLi4uPiwgc3RkOjp0dXBsZTwgc3RkOjp2ZWN0b3I8VHM+Li4uID5jb25zdCYgaW5wdXQgKSB7CiAgICAgICAgc3RkOjp2ZWN0b3I8IHN0ZDo6dHVwbGU8VHMuLi4+ID4gcmV0dmFsOwogICAgICAgIHJldHZhbC5yZXNlcnZlKCBwcm9kdWN0X3NpemUoIHN0ZDo6Z2V0PHM+KGlucHV0KS5zaXplKCkuLi4gKSApOwogICAgICAgIHN0ZDo6dmVjdG9yPHNpemVfdD4gbWF4ZXMgPSB7CiAgICAgICAgICAoc3RkOjpnZXQ8cz4oaW5wdXQpLnNpemUoKSkuLi4KICAgICAgICB9OwogICAgICAgIGZvcl9lYWNoX2luZGV4KCBtYXhlcywgWyZdKHN0ZDo6dmVjdG9yPHNpemVfdD4gY29uc3QmIGlkeCl7CiAgICAgICAgICByZXR2YWwuZW1wbGFjZV9iYWNrKCBzdGQ6OmdldDxzPihpbnB1dClbaWR4W3NdXS4uLiApOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiByZXR2YWw7CiAgICAgIH0KICAgIH0KICAgIHRlbXBsYXRlPHR5cGVuYW1lLi4uIFRzPgogICAgc3RkOjp2ZWN0b3I8IHN0ZDo6dHVwbGU8VHMuLi4+ID4gZG9lc19pdF9ibGVuZCggc3RkOjp0dXBsZTwgc3RkOjp2ZWN0b3I8VHM+Li4uID5jb25zdCYgaW5wdXQgKSB7CiAgICAgIHJldHVybiBkZXRhaWxzOjpkb2VzX2l0X2JsZW5kKCBNYWtlU2VxPCBzaXplb2YuLi4oVHMpID4oKSwgaW5wdXQgKTsKICAgIH0KICAgICAKICAgIGludCBtYWluKCkgewogICAgICBzdGQ6OnR1cGxlPCBzdGQ6OnZlY3RvcjxpbnQ+LCBzdGQ6OnZlY3Rvcjxib29sPiwgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+ID4gaW5wdXQgewogICAgICAgIHsgMSwgMiwgM30sIHsgZmFsc2UsIHRydWV9LCB7ICJIZWxsbyIsICJXb3JsZCJ9CiAgICAgIH07CiAgICAgCiAgICAgIC8vIHNob3VsZCBiZWNvbWUgMyB4IDIgeCAyID0gMTIgY2FzZXMgeyB7MSwgZmFsc2UsICJIZWxsbyJ9LCAuLi4gLCB7MywgdHJ1ZSwgIldvcmxkIn0gfSAKICAgICAgc3RkOjp2ZWN0b3I8IHN0ZDo6dHVwbGU8aW50LCBib29sLCBzdGQ6OnN0cmluZz4gPiB0ZXN0X2Nhc2VzID0gZG9lc19pdF9ibGVuZCggaW5wdXQgKTsKICAgICAgCiAgICAgIGZvciggYXV0byYmIHg6dGVzdF9jYXNlcyApIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgc3RkOjpnZXQ8MD4oeCkgPDwgIiwiIDw8IHN0ZDo6Z2V0PDE+KHgpIDw8ICIsIiA8PCBzdGQ6OmdldDwyPih4KSA8PCAiXG4iOwogICAgICB9CiAgICB9Cgo=
1,0,Hello
1,0,World
1,1,Hello
1,1,World
2,0,Hello
2,0,World
2,1,Hello
2,1,World
3,0,Hello
3,0,World
3,1,Hello
3,1,World