Skip to content

Commit 4075b5c

Browse files
authored
Allow using variadic templates instead of pre-generated code where supported (#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
1 parent 30f1a0a commit 4075b5c

16 files changed

+501
-43
lines changed

ChangeLog

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2024-05-23 Andrew Johnson <[email protected]>
2+
3+
* Added variadic templates to be used instead of the generated code
4+
in `Rcpp/generated` and `Rcpp/module` when compiling with C++11 or
5+
later.
6+
17
2024-05-18 Dirk Eddelbuettel <[email protected]>
28

39
* docker/ci-4.3/Dockerfile: Add rcpp/ci-4.3 container for R 4.3.*

inst/include/Rcpp/DataFrame.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,14 @@ namespace Rcpp{
117117
static DataFrame_Impl create(){
118118
return DataFrame_Impl() ;
119119
}
120-
121-
#include <Rcpp/generated/DataFrame_generated.h>
120+
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
121+
template <typename... T>
122+
static DataFrame_Impl create(const T&... args) {
123+
return DataFrame_Impl::from_list(Parent::create(args...));
124+
}
125+
#else
126+
#include <Rcpp/generated/DataFrame_generated.h>
127+
#endif
122128

123129
private:
124130
void set__(SEXP x){

inst/include/Rcpp/DottedPair.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ RCPP_API_CLASS(DottedPair_Impl),
3535
DottedPair_Impl(SEXP x) {
3636
Storage::set__(x) ;
3737
}
38-
39-
#include <Rcpp/generated/DottedPair__ctors.h>
38+
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
39+
template <typename... T>
40+
DottedPair_Impl(const T&... args) {
41+
Storage::set__(pairlist(args...));
42+
}
43+
#else
44+
#include <Rcpp/generated/DottedPair__ctors.h>
45+
#endif
4046

4147
void update(SEXP){}
4248

inst/include/Rcpp/Function.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,14 @@ namespace Rcpp{
8282
return Rcpp_fast_eval(call, R_GlobalEnv);
8383
}
8484

85-
#include <Rcpp/generated/Function__operator.h>
85+
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
86+
template <typename... T>
87+
SEXP operator()(const T&... args) const {
88+
return invoke(pairlist(args...), R_GlobalEnv);
89+
}
90+
#else
91+
#include <Rcpp/generated/Function__operator.h>
92+
#endif
8693

8794
/**
8895
* Returns the environment of this function

inst/include/Rcpp/InternalFunction.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ namespace Rcpp{
4747
)
4848
);
4949
}
50+
template <typename RESULT_TYPE, typename... T>
51+
InternalFunction_Impl(RESULT_TYPE (*fun)(T...)) {
52+
set(XPtr<CppFunctionN<RESULT_TYPE, T...> >(new CppFunctionN<RESULT_TYPE, T...>(fun), true));
53+
}
54+
#else
55+
#include <Rcpp/generated/InternalFunction__ctors.h>
5056
#endif
5157

52-
#include <Rcpp/generated/InternalFunction__ctors.h>
5358
void update(SEXP){}
5459
private:
5560

inst/include/Rcpp/InternalFunctionWithStdFunction.h

+6-19
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@
2323
#ifndef Rcpp_InternalFunctionWithStdFunction_h
2424
#define Rcpp_InternalFunctionWithStdFunction_h
2525

26+
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
27+
#include <Rcpp/internal/call.h>
28+
#endif
2629
#include <functional>
2730

2831
namespace Rcpp {
2932

3033
namespace InternalFunctionWithStdFunction {
31-
34+
#if !defined(HAS_VARIADIC_TEMPLATES) && !defined(RCPP_USING_CXX11)
3235
#include <Rcpp/generated/InternalFunctionWithStdFunction_call.h>
36+
#endif
3337

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

4044
SEXP operator()(SEXP* args) {
4145
BEGIN_RCPP
42-
auto result = call<RESULT_TYPE, Args...>(fun, args);
43-
return Rcpp::module_wrap<RESULT_TYPE>(result);
46+
return call<decltype(fun), RESULT_TYPE, Args...>(fun, args);
4447
END_RCPP
4548
}
4649

4750
private:
4851
const std::function<RESULT_TYPE(Args...)> fun;
4952
};
5053

51-
template <typename... Args>
52-
class CppFunctionBaseFromStdFunction<void, Args...> : public CppFunctionBase {
53-
public:
54-
CppFunctionBaseFromStdFunction(const std::function<void(Args...)> &fun) : fun(fun) {}
55-
virtual ~CppFunctionBaseFromStdFunction() {}
56-
57-
SEXP operator()(SEXP* args) {
58-
BEGIN_RCPP
59-
call<void, Args...>(fun, args);
60-
END_RCPP
61-
}
62-
63-
private:
64-
const std::function<void(Args...)> fun;
65-
};
66-
6754
} // namespace InternalFunctionWithStdFunction
6855
} // namespace Rcpp
6956

inst/include/Rcpp/Language.h

+13-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,19 @@ namespace Rcpp{
102102
* 0.0 is wrapped as a numeric vector using wrap( const& double )
103103
* ...
104104
*/
105-
#include <Rcpp/generated/Language__ctors.h>
105+
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
106+
template <typename... T>
107+
Language_Impl(const std::string& symbol, const T&... t) {
108+
Storage::set__(pairlist(Rf_install(symbol.c_str()), t...) );
109+
}
110+
111+
template <typename... T>
112+
Language_Impl(const Function& function, const T&... t) {
113+
Storage::set__(pairlist(function, t...));
114+
}
115+
#else
116+
#include <Rcpp/generated/Language__ctors.h>
117+
#endif
106118

107119
/**
108120
* sets the symbol of the call

0 commit comments

Comments
 (0)