// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include namespace Common { namespace Detail { template void CartesianInvokeImpl(Func func, OutputIt out_it, std::tuple& arglists_its, const std::tuple& arglists_tuple) { if constexpr (Level == N) { auto get_tuple = [&](std::index_sequence) { return std::forward_as_tuple(*std::get(arglists_its)...); }; *out_it++ = std::move(std::apply(func, get_tuple(std::make_index_sequence{}))); return; } else { const auto& arglist = std::get(arglists_tuple); for (auto it = arglist.begin(); it != arglist.end(); ++it) { std::get(arglists_its) = it; CartesianInvokeImpl( func, out_it, arglists_its, arglists_tuple); } } } } // namespace Detail template void CartesianInvoke(Func func, OutputIt out_it, const ArgLists&... arg_lists) { constexpr std::size_t N = sizeof...(ArgLists); const std::tuple arglists_tuple = std::forward_as_tuple(arg_lists...); std::tuple arglists_it; Detail::CartesianInvokeImpl(func, out_it, arglists_it, arglists_tuple); } } // namespace Common