Skip to content
Merged
Prev Previous commit
Next Next commit
Variadic templates for pointer methods
  • Loading branch information
andrjohns committed May 23, 2024
commit 6f0bad131cef1491b03c280f0bb4ff80501a362b
95 changes: 93 additions & 2 deletions inst/include/Rcpp/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,6 @@ bool yes_arity( SEXP* /* args */ , int nargs){
RESULT_TYPE operator_impl(Class* object, SEXP* args, traits::index_sequence<Is...>) {
return (object->*met)((typename traits::input_parameter<T>::type(args[Is]))...);
}

};

template <typename Class, typename... T> class CppMethodN<Class, void, T...> : public CppMethod<Class> {
Expand Down Expand Up @@ -524,10 +523,102 @@ bool yes_arity( SEXP* /* args */ , int nargs){
(object->*met)((typename traits::input_parameter<T>::type(args[Is]))...);
}
};

template <typename Class, typename RESULT_TYPE, typename... T> class Pointer_CppMethodN : public CppMethod<Class> {
public:
typedef RESULT_TYPE (*Method)(Class*, T...);
typedef CppMethod<Class> method_class;
typedef typename Rcpp::traits::remove_const_and_reference<RESULT_TYPE>::type CLEANED_RESULT_TYPE;

Pointer_CppMethodN(Method m) : method_class(), met(m) {}
SEXP operator()(Class* object, SEXP* args) {
return Rcpp::module_wrap<CLEANED_RESULT_TYPE>(operator_impl(object, args, traits::make_index_sequence<sizeof...(T)>()));
}
inline int nargs() { return sizeof...(T); }
inline bool is_void() { return false; }
inline bool is_const() { return false; }
inline void signature(std::string& s, const char* name) { Rcpp::signature<RESULT_TYPE,T...>(s, name); }
private:
Method met;

template <int... Is>
RESULT_TYPE operator_impl(Class* object, SEXP* args, traits::index_sequence<Is...>) {
return met(object, (typename traits::input_parameter<T>::type(args[Is]))...);
}
};

template <typename Class, typename... T> class Pointer_CppMethodN<Class, void, T...> : public CppMethod<Class> {
public:
typedef void (*Method)(Class*, T...);
typedef CppMethod<Class> method_class;

Pointer_CppMethodN(Method m) : method_class(), met(m) {}
SEXP operator()(Class* object, SEXP* args) {
operator_impl(object, args, traits::make_index_sequence<sizeof...(T)>());
return R_NilValue;
}
inline int nargs() { return sizeof...(T); }
inline bool is_void() { return true; }
inline bool is_const() { return false; }
inline void signature(std::string& s, const char* name) { Rcpp::signature<void_type,T...>(s, name); }
private:
Method met;

template <int... Is>
void operator_impl(Class* object, SEXP* args, traits::index_sequence<Is...>) {
met(object, (typename traits::input_parameter<T>::type(args[Is]))...);
}
};

template <typename Class, typename RESULT_TYPE, typename... T> class Const_Pointer_CppMethodN : public CppMethod<Class> {
public:
typedef RESULT_TYPE (*Method)(const Class*, T...);
typedef CppMethod<Class> method_class;
typedef typename Rcpp::traits::remove_const_and_reference<RESULT_TYPE>::type CLEANED_RESULT_TYPE;

Const_Pointer_CppMethodN(Method m) : method_class(), met(m) {}
SEXP operator()(Class* object, SEXP* args) {
return Rcpp::module_wrap<CLEANED_RESULT_TYPE>(operator_impl(object, args, traits::make_index_sequence<sizeof...(T)>()));
}
inline int nargs() { return sizeof...(T); }
inline bool is_void() { return false; }
inline bool is_const() { return true; }
inline void signature(std::string& s, const char* name) { Rcpp::signature<RESULT_TYPE,T...>(s, name); }
private:
Method met;

template <int... Is>
RESULT_TYPE operator_impl(Class* object, SEXP* args, traits::index_sequence<Is...>) {
return met(object, (typename traits::input_parameter<T>::type(args[Is]))...);
}
};

template <typename Class, typename... T> class Const_Pointer_CppMethodN<Class, void, T...> : public CppMethod<Class> {
public:
typedef void (*Method)(const Class*, T...);
typedef CppMethod<Class> method_class;

Const_Pointer_CppMethodN(Method m) : method_class(), met(m) {}
SEXP operator()(Class* object, SEXP* args) {
operator_impl(object, args, traits::make_index_sequence<sizeof...(T)>());
return R_NilValue;
}
inline int nargs() { return sizeof...(T); }
inline bool is_void() { return true; }
inline bool is_const() { return true; }
inline void signature(std::string& s, const char* name) { Rcpp::signature<void_type,T...>(s, name); }
private:
Method met;

template <int... Is>
void operator_impl(Class* object, SEXP* args, traits::index_sequence<Is...>) {
met(object, (typename traits::input_parameter<T>::type(args[Is]))...);
}
};
#else
#include <Rcpp/module/Module_generated_CppMethod.h>
#include <Rcpp/module/Module_generated_Pointer_CppMethod.h>
#endif
#include <Rcpp/module/Module_generated_Pointer_CppMethod.h>

template <typename Class>
class CppProperty {
Expand Down
14 changes: 13 additions & 1 deletion inst/include/Rcpp/module/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,22 @@
AddMethod( name_, new const_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
return *this;
}
template <typename RESULT_TYPE, typename... T>
self& method(const char* name_, RESULT_TYPE (*fun)(Class*, T...),
const char* docstring = 0, ValidMethod valid = &yes_arity<sizeof...(T)>) {
AddMethod( name_, new Pointer_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
return *this;
}
template <typename RESULT_TYPE, typename... T>
self& const_method(const char* name_, RESULT_TYPE (*fun)(const Class*, T...),
const char* docstring = 0, ValidMethod valid = &yes_arity<sizeof...(T)>) {
AddMethod( name_, new Const_Pointer_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
return *this;
}
#else
#include <Rcpp/module/Module_generated_method.h>
#include <Rcpp/module/Module_generated_Pointer_method.h>
#endif
#include <Rcpp/module/Module_generated_Pointer_method.h>

bool has_method( const std::string& m){
return vec_methods.find(m) != vec_methods.end() ;
Expand Down