Skip to content

Commit

Permalink
Allow using variadic templates instead of pre-generated code where su…
Browse files Browse the repository at this point in the history
…pported (#1303)

* Replace generated code with variadic templates where supported

* Template outside of ifdef

* Add variadic templates for Language,Vector,InternalStdFunction

* Cleanup placement of new traits

* Initial implementations of more templates

* Fix stray changes

* Variadic template for generated methods

* Variadic templates for pointer methods

* Simplify and reduce duplication of templates

* Simplify more templates

* Add changelog entry

* Fix incorrect template type for Factory constructor
  • Loading branch information
andrjohns authored May 26, 2024
1 parent 30f1a0a commit 4075b5c
Show file tree
Hide file tree
Showing 16 changed files with 501 additions and 43 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2024-05-23 Andrew Johnson <andrew.johnson@arjohnsonau.com>

* Added variadic templates to be used instead of the generated code
in `Rcpp/generated` and `Rcpp/module` when compiling with C++11 or
later.

2024-05-18 Dirk Eddelbuettel <edd@debian.org>

* docker/ci-4.3/Dockerfile: Add rcpp/ci-4.3 container for R 4.3.*
Expand Down
10 changes: 8 additions & 2 deletions inst/include/Rcpp/DataFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,14 @@ namespace Rcpp{
static DataFrame_Impl create(){
return DataFrame_Impl() ;
}

#include <Rcpp/generated/DataFrame_generated.h>
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
template <typename... T>
static DataFrame_Impl create(const T&... args) {
return DataFrame_Impl::from_list(Parent::create(args...));
}
#else
#include <Rcpp/generated/DataFrame_generated.h>
#endif

private:
void set__(SEXP x){
Expand Down
10 changes: 8 additions & 2 deletions inst/include/Rcpp/DottedPair.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,14 @@ RCPP_API_CLASS(DottedPair_Impl),
DottedPair_Impl(SEXP x) {
Storage::set__(x) ;
}

#include <Rcpp/generated/DottedPair__ctors.h>
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
template <typename... T>
DottedPair_Impl(const T&... args) {
Storage::set__(pairlist(args...));
}
#else
#include <Rcpp/generated/DottedPair__ctors.h>
#endif

void update(SEXP){}

Expand Down
9 changes: 8 additions & 1 deletion inst/include/Rcpp/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,14 @@ namespace Rcpp{
return Rcpp_fast_eval(call, R_GlobalEnv);
}

#include <Rcpp/generated/Function__operator.h>
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
template <typename... T>
SEXP operator()(const T&... args) const {
return invoke(pairlist(args...), R_GlobalEnv);
}
#else
#include <Rcpp/generated/Function__operator.h>
#endif

/**
* Returns the environment of this function
Expand Down
7 changes: 6 additions & 1 deletion inst/include/Rcpp/InternalFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,14 @@ namespace Rcpp{
)
);
}
template <typename RESULT_TYPE, typename... T>
InternalFunction_Impl(RESULT_TYPE (*fun)(T...)) {
set(XPtr<CppFunctionN<RESULT_TYPE, T...> >(new CppFunctionN<RESULT_TYPE, T...>(fun), true));
}
#else
#include <Rcpp/generated/InternalFunction__ctors.h>
#endif

#include <Rcpp/generated/InternalFunction__ctors.h>
void update(SEXP){}
private:

Expand Down
25 changes: 6 additions & 19 deletions inst/include/Rcpp/InternalFunctionWithStdFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
#ifndef Rcpp_InternalFunctionWithStdFunction_h
#define Rcpp_InternalFunctionWithStdFunction_h

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#include <Rcpp/internal/call.h>
#endif
#include <functional>

namespace Rcpp {

namespace InternalFunctionWithStdFunction {

#if !defined(HAS_VARIADIC_TEMPLATES) && !defined(RCPP_USING_CXX11)
#include <Rcpp/generated/InternalFunctionWithStdFunction_call.h>
#endif

template <typename RESULT_TYPE, typename... Args>
class CppFunctionBaseFromStdFunction : public CppFunctionBase {
Expand All @@ -39,31 +43,14 @@ namespace Rcpp {

SEXP operator()(SEXP* args) {
BEGIN_RCPP
auto result = call<RESULT_TYPE, Args...>(fun, args);
return Rcpp::module_wrap<RESULT_TYPE>(result);
return call<decltype(fun), RESULT_TYPE, Args...>(fun, args);
END_RCPP
}

private:
const std::function<RESULT_TYPE(Args...)> fun;
};

template <typename... Args>
class CppFunctionBaseFromStdFunction<void, Args...> : public CppFunctionBase {
public:
CppFunctionBaseFromStdFunction(const std::function<void(Args...)> &fun) : fun(fun) {}
virtual ~CppFunctionBaseFromStdFunction() {}

SEXP operator()(SEXP* args) {
BEGIN_RCPP
call<void, Args...>(fun, args);
END_RCPP
}

private:
const std::function<void(Args...)> fun;
};

} // namespace InternalFunctionWithStdFunction
} // namespace Rcpp

Expand Down
14 changes: 13 additions & 1 deletion inst/include/Rcpp/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,19 @@ namespace Rcpp{
* 0.0 is wrapped as a numeric vector using wrap( const& double )
* ...
*/
#include <Rcpp/generated/Language__ctors.h>
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
template <typename... T>
Language_Impl(const std::string& symbol, const T&... t) {
Storage::set__(pairlist(Rf_install(symbol.c_str()), t...) );
}

template <typename... T>
Language_Impl(const Function& function, const T&... t) {
Storage::set__(pairlist(function, t...));
}
#else
#include <Rcpp/generated/Language__ctors.h>
#endif

/**
* sets the symbol of the call
Expand Down
Loading

0 comments on commit 4075b5c

Please sign in to comment.