namespace seafire::common { template Ret do_invoke(T& target, server::request_t& req, Direct const&... direct, Ret (T::*func)(Direct const&..., Params const&...)) { return (target.*func)(direct..., std::decay_t::fetch(req)...); } template Ret invoke(T& target, server::request_t& req, Ret (T::*func)(Params const&...), Direct const&... direct) { return do_invoke(target, req, direct..., func); } template Ret do_invoke(T const& target, server::request_t& req, Direct const&... direct, Ret (T::*func)(Direct const&..., Params const&...) const) { return (target.*func)(direct..., std::decay_t::fetch(req)...); } template Ret invoke(T const& target, server::request_t& req, Ret (T::*func)(Params const&...) const, Direct const&... direct) { return do_invoke(target, req, direct..., func); } template Ret do_invoke(server::request_t& req, Direct&&... direct, Ret (*func)(Direct..., Params...)) { return (*func)(direct..., std::decay_t::fetch(req)...); } template Ret invoke(server::request_t& req, Ret (*func)(Params...), Direct&&... direct) { return do_invoke(req, direct..., func); } } // namespace seafire::common