#pragma once #include #include #include #include #include template void print_tuple(const TupType& _tup, std::index_sequence) { std::cout << "("; (..., (std::cout << (I == 0? "" : ", ") << std::get(_tup))); std::cout << ")\n"; } template void print_tuple(const std::tuple& _tup) { print_tuple(_tup, std::make_index_sequence()); } template void variatic_min(std::vector v, int &m) { if (m > v.size()) m = v.size(); } template using NthTypeOf = typename std::tuple_element>::type; template auto vec_to_tup_helper(const std::vector& v, std::index_sequence) { return std::make_tuple( std::any_cast>(v[Indices])... ); } template std::tuple vec_to_tup(std::vector& values) { return vec_to_tup_helper(values, std::make_index_sequence()); } template void celem_at(std::vector v, int i, std::vector &r) { r.push_back(v[i]); } template std::vector> zip(std::vector... args) { int m = 0xFFFFFFFF; std::vector> res; (variatic_min(args, m), ...); for (int i = 0; i < m; i++) { std::vector vaux; (celem_at(args, i, vaux), ...); res.push_back(vec_to_tup(vaux)); } return res; }