#include<tuple>
#include<vector>
#include<iostream>
template<typename... Ps>
inline void
cross_imp(std::tuple<Ps...> pref, std::vector<std::tuple<Ps...>>& out)
{
out.push_back(pref);
}
template<typename... Ps, typename H, typename... Ts>
inline void
cross_imp(std::tuple<Ps...> pref,
std::vector<std::tuple<Ps..., H, Ts...>>& out,
std::vector<H> h, std::vector<Ts>... t)
{
for(H he: h)
cross_imp(std::tuple_cat(pref, std::make_tuple(he)), out, t...);
}
template<typename... Ts>
std::vector<std::tuple<Ts...>>
cross(std::vector<Ts>... in)
{
std::vector<std::tuple<Ts...>> res;
cross_imp(std::tuple<>(), res, in...);
return res;
}
#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>
template<size_t N>
struct Apply {
template<typename F, typename T, typename... A>
static inline auto apply(F&& f, T && t, A &&... a)
-> decltype(Apply<N-1>::apply(::std::forward<F>(f), ::std::forward<T>(t),
::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
))
{
return Apply<N-1>::apply(::std::forward<F>(f), ::std::forward<T>(t),
::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
);
}
};
template<>
struct Apply<0> {
template<typename F, typename T, typename... A>
static inline auto apply(F && f, T &&, A &&... a)
-> decltype(f(::std::forward<A>(a)...))
{
return f(::std::forward<A>(a)...);
}
};
template<typename F, typename T>
inline auto apply(F && f, T && t)
-> decltype(Apply< ::std::tuple_size<
typename ::std::decay<T>::type
>::value>::apply(::std::forward<F>(f), ::std::forward<T>(t)))
{
return Apply< ::std::tuple_size<
typename ::std::decay<T>::type
>::value>::apply(f, ::std::forward<T>(t));
}
int main() {
std::vector<int> is = { 2, 5, 9 };
std::vector<char const*> cps = { "foo","bar" };
std::vector<float> fs = { 1.5, 9.3, 1.2 };
std::vector<double> ds = { 9.2,-2.1, 2.3 };
#ifdef DIRECT_CALL
auto result = cross( is, cps, fs, ds );
#else
std::vector< std::tuple<int,char const*,float,double> > result
= apply( cross, std::make_tuple( is, cps, fs, ds ));
#endif
for(auto& a: result) {
std::cout << '{'
<< std::get<0>(a) << ','
<< std::get<1>(a) << ','
<< std::get<2>(a) << ','
<< std::get<3>(a)
<< '}' << std::endl;
}
}
I2luY2x1ZGU8dHVwbGU+CiNpbmNsdWRlPHZlY3Rvcj4KCiNpbmNsdWRlPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gUHM+CmlubGluZSB2b2lkIApjcm9zc19pbXAoc3RkOjp0dXBsZTxQcy4uLj4gcHJlZiwgc3RkOjp2ZWN0b3I8c3RkOjp0dXBsZTxQcy4uLj4+JiBvdXQpIAp7CiAgICBvdXQucHVzaF9iYWNrKHByZWYpOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBQcywgdHlwZW5hbWUgSCwgdHlwZW5hbWUuLi4gVHM+CmlubGluZSB2b2lkIApjcm9zc19pbXAoc3RkOjp0dXBsZTxQcy4uLj4gcHJlZiwKICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPHN0ZDo6dHVwbGU8UHMuLi4sIEgsIFRzLi4uPj4mIG91dCwKICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPEg+IGgsIHN0ZDo6dmVjdG9yPFRzPi4uLiB0KSAKewogICAgZm9yKEggaGU6IGgpCgkJY3Jvc3NfaW1wKHN0ZDo6dHVwbGVfY2F0KHByZWYsIHN0ZDo6bWFrZV90dXBsZShoZSkpLCBvdXQsIHQuLi4pOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBUcz4Kc3RkOjp2ZWN0b3I8c3RkOjp0dXBsZTxUcy4uLj4+IApjcm9zcyhzdGQ6OnZlY3RvcjxUcz4uLi4gaW4pIAp7CglzdGQ6OnZlY3RvcjxzdGQ6OnR1cGxlPFRzLi4uPj4gcmVzOwoJY3Jvc3NfaW1wKHN0ZDo6dHVwbGU8PigpLCByZXMsIGluLi4uKTsKCXJldHVybiByZXM7Cn0KCiNpbmNsdWRlIDxjc3RkZGVmPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KI2luY2x1ZGUgPHV0aWxpdHk+Cgp0ZW1wbGF0ZTxzaXplX3QgTj4Kc3RydWN0IEFwcGx5IHsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEYsIHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEE+CiAgICBzdGF0aWMgaW5saW5lIGF1dG8gYXBwbHkoRiYmIGYsIFQgJiYgdCwgQSAmJi4uLiBhKQogICAgICAgIC0+IGRlY2x0eXBlKEFwcGx5PE4tMT46OmFwcGx5KDo6c3RkOjpmb3J3YXJkPEY+KGYpLCA6OnN0ZDo6Zm9yd2FyZDxUPih0KSwKICAgICAgICAgICAgOjpzdGQ6OmdldDxOLTE+KDo6c3RkOjpmb3J3YXJkPFQ+KHQpKSwgOjpzdGQ6OmZvcndhcmQ8QT4oYSkuLi4KICAgICAgICApKQogICAgewogICAgICAgIHJldHVybiBBcHBseTxOLTE+OjphcHBseSg6OnN0ZDo6Zm9yd2FyZDxGPihmKSwgOjpzdGQ6OmZvcndhcmQ8VD4odCksCiAgICAgICAgICAgIDo6c3RkOjpnZXQ8Ti0xPig6OnN0ZDo6Zm9yd2FyZDxUPih0KSksIDo6c3RkOjpmb3J3YXJkPEE+KGEpLi4uCiAgICAgICAgKTsKICAgIH0KfTsKCnRlbXBsYXRlPD4Kc3RydWN0IEFwcGx5PDA+IHsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEYsIHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEE+CiAgICBzdGF0aWMgaW5saW5lIGF1dG8gYXBwbHkoRiAmJiBmLCBUICYmLCBBICYmLi4uIGEpCiAgICAgICAgLT4gZGVjbHR5cGUoZig6OnN0ZDo6Zm9yd2FyZDxBPihhKS4uLikpCiAgICB7CiAgICAgICAgcmV0dXJuIGYoOjpzdGQ6OmZvcndhcmQ8QT4oYSkuLi4pOwogICAgfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgRiwgdHlwZW5hbWUgVD4KaW5saW5lIGF1dG8gYXBwbHkoRiAmJiBmLCBUICYmIHQpCiAgICAgLT4gZGVjbHR5cGUoQXBwbHk8IDo6c3RkOjp0dXBsZV9zaXplPAogICAgICAgICB0eXBlbmFtZSA6OnN0ZDo6ZGVjYXk8VD46OnR5cGUKICAgICA+Ojp2YWx1ZT46OmFwcGx5KDo6c3RkOjpmb3J3YXJkPEY+KGYpLCA6OnN0ZDo6Zm9yd2FyZDxUPih0KSkpCnsKICAgIHJldHVybiBBcHBseTwgOjpzdGQ6OnR1cGxlX3NpemU8CiAgICAgICAgdHlwZW5hbWUgOjpzdGQ6OmRlY2F5PFQ+Ojp0eXBlCiAgICA+Ojp2YWx1ZT46OmFwcGx5KGYsIDo6c3RkOjpmb3J3YXJkPFQ+KHQpKTsKfQoKaW50IG1haW4oKSB7CglzdGQ6OnZlY3RvcjxpbnQ+ICAgICAgICAgaXMgID0geyAyLCA1LCA5IH07CglzdGQ6OnZlY3RvcjxjaGFyIGNvbnN0Kj4gY3BzID0geyAiZm9vIiwiYmFyIiB9OwoJc3RkOjp2ZWN0b3I8ZmxvYXQ+ICAgICAgIGZzICA9IHsgMS41LCA5LjMsIDEuMiB9OwoJc3RkOjp2ZWN0b3I8ZG91YmxlPiAgICAgIGRzICA9IHsgOS4yLC0yLjEsIDIuMyB9OwoKI2lmZGVmIERJUkVDVF9DQUxMCglhdXRvIHJlc3VsdCA9IGNyb3NzKCBpcywgY3BzLCBmcywgZHMgKTsKI2Vsc2UKCXN0ZDo6dmVjdG9yPCBzdGQ6OnR1cGxlPGludCxjaGFyIGNvbnN0KixmbG9hdCxkb3VibGU+ID4gcmVzdWx0CgkJPSBhcHBseSggY3Jvc3MsIHN0ZDo6bWFrZV90dXBsZSggaXMsIGNwcywgZnMsIGRzICkpOyAgICAKI2VuZGlmCgoJZm9yKGF1dG8mIGE6IHJlc3VsdCkgewoJCXN0ZDo6Y291dCA8PCAneycgCgkJCTw8IHN0ZDo6Z2V0PDA+KGEpIDw8ICcsJyAKCQkJPDwgc3RkOjpnZXQ8MT4oYSkgPDwgJywnIAoJCQk8PCBzdGQ6OmdldDwyPihhKSA8PCAnLCcgCgkJCTw8IHN0ZDo6Z2V0PDM+KGEpIAoJCTw8ICd9JyA8PCBzdGQ6OmVuZGw7Cgl9Cn0=