Whereas you can do some REPEAT MACRO (which would forward to REPEAT_3, REPEAT_2 and REPEAT_1) and would have some hard coded limit,
you might use instead template for the generation, for example:
template <typename T, std::size_t> using always_t = T;
template <typename T, typename Seq> struct gen_tuple_helper;
template <typename T, std::size_t ... Is>
struct gen_tuple_helper
{
using type = std::tuple<always_t<T, Is>...>;
};
template <typename T, std::size_t N>
using gen_tuple_t = typename gen_tuple_helper<T, std::make_index_sequence<T>>::type;
static_assert(std::is_same_v<std::tuple<int, int, int>, gen_tuple_t<int, 3>>);
Note: As noted in comment homogeneous std::tuple
might be replaced by std::array
which seems simpler to manipulate.