1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
#ifndef RCPP_INTERNAL_CALL_H
#define RCPP_INTERNAL_CALL_H
#include <Rcpp/traits/index_sequence.h>
#include <functional>
namespace Rcpp {
namespace internal {
// Utility struct so that we can pass a pack of types between functions
template <typename... T> struct type_pack {};
/**
* This specialisation is for functions that return a value, whereas the below
* is for void-returning functions.
*
* The "* = nullptr" default argument allows both templates to be well-defined
* regardless of which one is used.
*/
template <typename F, typename RESULT_TYPE, typename... Us, int... Is,
typename std::enable_if<!std::is_void<RESULT_TYPE>::value>::type* = nullptr>
SEXP call_impl(const F& fun, SEXP* args, type_pack<RESULT_TYPE, Us...>,
traits::index_sequence<Is...>) {
RESULT_TYPE res = fun((typename traits::input_parameter<Us>::type(args[Is]))...);
return Rcpp::module_wrap<RESULT_TYPE>(res);
}
template <typename F, typename RESULT_TYPE, typename... Us, int... Is,
typename std::enable_if<std::is_void<RESULT_TYPE>::value>::type* = nullptr>
SEXP call_impl(const F& fun, SEXP* args, type_pack<RESULT_TYPE, Us...>,
traits::index_sequence<Is...>) {
fun((typename traits::input_parameter<Us>::type(args[Is]))...);
return R_NilValue;
}
} // namespace internal
/**
* Helper for calling a function with an array of SEXP arguments,
* where each argument is converted to the appropriate type before being passed
* to the function. A compile-time sequence is used to index the SEXP array.
*
* The function only needs the intended types of the result and arguments,
* which allows the template to be used for function pointers, lambdas, and
* `std::function` objects.
*/
template <typename F, typename RESULT_TYPE, typename... Us>
SEXP call(const F& fun, SEXP* args) {
return internal::call_impl(fun, args,
internal::type_pack<RESULT_TYPE, Us...>{},
traits::make_index_sequence<sizeof...(Us)>{});
}
} // namespace Rcpp
#endif
|