93 lines
2.4 KiB
C
93 lines
2.4 KiB
C
|
#pragma once
|
||
|
|
||
|
#ifndef CALL_H_ZXFACADH
|
||
|
#define CALL_H_ZXFACADH
|
||
|
|
||
|
#include <tuple>
|
||
|
#include "rpc/detail/func_tools.h"
|
||
|
#include "rpc/detail/invoke.h"
|
||
|
#include "rpc/detail/is_specialization_of.h"
|
||
|
|
||
|
namespace rpc {
|
||
|
namespace detail {
|
||
|
|
||
|
//! \brief Calls a functor with argument provided directly
|
||
|
template <typename Functor, typename Arg>
|
||
|
auto call(Functor f, Arg &&arg)
|
||
|
-> decltype(f(std::forward<Arg>(arg)))
|
||
|
{
|
||
|
return f(std::forward<Arg>(arg));
|
||
|
}
|
||
|
|
||
|
|
||
|
// Default behaviour is to assume C++11, overriding RPCLIB_CXX_STANDARD can use
|
||
|
// newer standards:
|
||
|
#if RPCLIB_CXX_STANDARD >= 14
|
||
|
|
||
|
template <typename Functor, typename... Args, std::size_t... I>
|
||
|
decltype(auto) call_helper(Functor func, std::tuple<Args...> &¶ms,
|
||
|
std::index_sequence<I...>) {
|
||
|
return func(std::get<I>(params)...);
|
||
|
}
|
||
|
|
||
|
//! \brief Calls a functor with arguments provided as a tuple
|
||
|
template <typename Functor, typename... Args>
|
||
|
decltype(auto) call(Functor f, std::tuple<Args...> &args) {
|
||
|
return call_helper(f, std::forward<std::tuple<Args...>>(args),
|
||
|
std::index_sequence_for<Args...>{});
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
// N is number of arguments left in tuple to unpack
|
||
|
|
||
|
template <size_t N>
|
||
|
struct call_helper
|
||
|
{
|
||
|
template <typename Functor, typename... ArgsT, typename... ArgsF>
|
||
|
static auto call(
|
||
|
Functor f,
|
||
|
std::tuple<ArgsT...>& args_t,
|
||
|
ArgsF&&... args_f)
|
||
|
-> decltype(call_helper<N-1>::call(
|
||
|
f, args_t, std::get<N-1>(args_t),
|
||
|
std::forward<ArgsF>(args_f)...))
|
||
|
{
|
||
|
return call_helper<N-1>::call(
|
||
|
f,
|
||
|
args_t,
|
||
|
std::get<N-1>(args_t),
|
||
|
std::forward<ArgsF>(args_f)...
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <>
|
||
|
struct call_helper<0>
|
||
|
{
|
||
|
template <typename Functor, typename... ArgsT, typename... ArgsF>
|
||
|
static auto call(
|
||
|
Functor f,
|
||
|
std::tuple<ArgsT...>&,
|
||
|
ArgsF&&... args_f)
|
||
|
-> decltype(f(std::forward<ArgsF>(args_f)...))
|
||
|
{
|
||
|
return f(std::forward<ArgsF>(args_f)...);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//! \brief Calls a functor with arguments provided as a tuple
|
||
|
template <typename Functor, typename... ArgsT>
|
||
|
auto call(Functor f, std::tuple<ArgsT...>& args_t)
|
||
|
-> decltype(call_helper<sizeof...(ArgsT)>::call(f, args_t))
|
||
|
{
|
||
|
return call_helper<sizeof...(ArgsT)>::call(f, args_t);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif /* end of include guard: CALL_H_ZXFACADH */
|