#pragma once #include "functional4.hpp" #include "tuple.hpp" namespace ck { template __host__ __device__ constexpr auto generate_tuple(F&& f, Number) { return unpack([&f](auto&&... xs) { return make_tuple(f(xs)...); }, typename arithmetic_sequence_gen<0, N, 1>::type{}); } template __host__ __device__ constexpr auto generate_tie(F&& f, Number) { return unpack([&f](auto&&... xs) { return tie(f(xs)...); }, typename arithmetic_sequence_gen<0, N, 1>::type{}); } // tx and ty are tuple of references, return type of will tuple of referennce (not rvalue) template __host__ __device__ constexpr auto concat_tuple_of_reference(const Tuple& tx, const Tuple& ty) { return unpack2( [&](auto&&... zs) { return Tuple{std::forward(zs)...}; }, tx, ty); } namespace detail { template __host__ __device__ constexpr auto transform_tuples_impl(F f, const X& x, Sequence) { return make_tuple(f(x.At(Number{}))...); } template __host__ __device__ constexpr auto transform_tuples_impl(F f, const X& x, const Y& y, Sequence) { return make_tuple(f(x.At(Number{}), y.At(Number{}))...); } template __host__ __device__ constexpr auto transform_tuples_impl(F f, const X& x, const Y& y, const Z& z, Sequence) { return make_tuple(f(x.At(Number{}), y.At(Number{}), z.At(Number{}))...); } } // namespace detail template __host__ __device__ constexpr auto transform_tuples(F f, const X& x) { return detail::transform_tuples_impl( f, x, typename arithmetic_sequence_gen<0, X::Size(), 1>::type{}); } template __host__ __device__ constexpr auto transform_tuples(F f, const X& x, const Y& y) { return detail::transform_tuples_impl( f, x, y, typename arithmetic_sequence_gen<0, X::Size(), 1>::type{}); } template __host__ __device__ constexpr auto transform_tuples(F f, const X& x, const Y& y, const Z& z) { return detail::transform_tuples_impl( f, x, y, z, typename arithmetic_sequence_gen<0, X::Size(), 1>::type{}); } } // namespace ck