#ifndef MIGRAPHX_GUARD_RTGLIB_FUNCTIONAL_HPP #define MIGRAPHX_GUARD_RTGLIB_FUNCTIONAL_HPP #include #include namespace migraphx { inline namespace MIGRAPHX_INLINE_NS { struct swallow { template constexpr swallow(Ts&&...) { } }; template auto tuple_size(const T&) { return typename std::tuple_size::type{}; } namespace detail { template struct fix_f { F f; template R operator()(Ts&&... xs) const { return f(*this, std::forward(xs)...); } }; template struct seq { using type = seq; }; template struct merge_seq; template struct merge_seq, seq> : seq { }; template struct gens : merge_seq::type, typename gens::type> { }; template <> struct gens<0> : seq<> { }; template <> struct gens<1> : seq<0> { }; template constexpr void repeat_c_impl(F f, seq) { swallow{(f(std::integral_constant{}), 0)...}; } template constexpr auto sequence_c_impl(F&& f, seq) { return f(std::integral_constant{}...); } } // namespace detail template constexpr void repeat_c(F f) { detail::repeat_c_impl(f, detail::gens{}); } template constexpr auto sequence_c(F&& f) { return detail::sequence_c_impl(f, detail::gens{}); } template constexpr auto sequence(IntegerConstant ic, F&& f) { return sequence_c(f); } template constexpr void each_args(F f, Ts&&... xs) { swallow{(f(std::forward(xs)), 0)...}; } template constexpr void each_args(F) { } template auto unpack(F f, T&& x) { return sequence(tuple_size(x), [&](auto... is) { f(std::get(static_cast(x))...); }); } /// Implements a fix-point combinator template detail::fix_f fix(F f) { return {f}; } template auto fix(F f) { return fix(f); } template auto fold_impl(F&&, T&& x) { return std::forward(x); } template auto fold_impl(F&& f, T&& x, U&& y, Ts&&... xs) { return fold_impl(f, f(std::forward(x), std::forward(y)), std::forward(xs)...); } template auto fold(F f) { return [=](auto&&... xs) { return fold_impl(f, std::forward(xs)...); }; } template auto pack(Ts... xs) { return [=](auto f) { return f(xs...); }; } inline auto pack_join() { return pack(); } template auto pack_join(Ps... ps) { return fold([](auto p1, auto p2) { return p1([=](auto... xs) { return p2([=](auto... ys) { return pack(xs..., ys...); }); }); })(ps...); } template auto by(F f, Proj proj) { return [=](auto&&... xs) { return f(proj(std::forward(xs))...); }; } template auto index_of(T& x) { return [&](auto&& y) { return x[y]; }; } template decltype(auto) front_args(T&& x, Ts&&...) { return static_cast(x); } template decltype(auto) back_args(Ts&&... xs) { return std::get(std::tuple(static_cast(xs)...)); } template auto pop_front_args(T&&, Ts&&... xs) { return [&](auto f) { f(static_cast(xs)...); }; } template auto pop_back_args(Ts&&... xs) { return [&](auto f) { using tuple_type = std::tuple; auto t = tuple_type(static_cast(xs)...); return sequence_c( [&](auto... is) { return f(std::get(static_cast(t))...); }); }; } template struct always_f { T x; template constexpr T operator()(Ts&&...) const { return x; } }; template auto always(T x) { return always_f{x}; } struct id { template constexpr T operator()(T&& x) const { return static_cast(x); } }; template void nop(Ts&&...) { } } // namespace MIGRAPHX_INLINE_NS } // namespace migraphx #endif