Skip to content

Commit c91eb89

Browse files
authored
Variadic templates refinement (#1336)
* add tests to check that void functions return invisibly * uncomment HAS_VARIADIC_TEMPLATES capability, simplify ifdefs * add missing is_void method to CppFunctionN * update ChangeLog
1 parent 982f784 commit c91eb89

17 files changed

+70
-24
lines changed

ChangeLog

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
2024-10-07 Iñaki Ucar <[email protected]>
2+
3+
* inst/include/Rcpp/platform/compiler.h: Uncomment HAS_VARIADIC_TEMPLATES
4+
macro definition
5+
* src/api.cpp: Simplify checks for variadic templates
6+
* inst/include/Rcpp/DataFrame.h: Idem
7+
* inst/include/Rcpp/DottedPair.h: Idem
8+
* inst/include/Rcpp/Function.h: Idem
9+
* inst/include/Rcpp/InternalFunctionWithStdFunction.h: Idem
10+
* inst/include/Rcpp/Language.h: Idem
11+
* inst/include/Rcpp/Pairlist.h: Idem
12+
* inst/include/Rcpp/grow.h: Idem
13+
* inst/include/Rcpp/internal/call.h: Idem
14+
* inst/include/Rcpp/module/class.h: Idem
15+
* inst/include/Rcpp/traits/index_sequence.h: Idem
16+
* inst/include/Rcpp/traits/named_object.h: Idem
17+
* inst/include/Rcpp/vector/Vector.h: Idem
18+
* inst/include/Rcpp/Module.h: Idem + add missing is_void method
19+
* inst/tinytest/test_module.R: Add test for void functions and methods
20+
121
2024-10-04 Dirk Eddelbuettel <[email protected]>
222

323
* DESCRIPTION (Version, Date): Roll micro version to 1.0.13.3

inst/include/Rcpp/DataFrame.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ namespace Rcpp{
117117
static DataFrame_Impl create(){
118118
return DataFrame_Impl() ;
119119
}
120-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
120+
#if defined(HAS_VARIADIC_TEMPLATES)
121121
template <typename... T>
122122
static DataFrame_Impl create(const T&... args) {
123123
return DataFrame_Impl::from_list(Parent::create(args...));

inst/include/Rcpp/DottedPair.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ RCPP_API_CLASS(DottedPair_Impl),
3535
DottedPair_Impl(SEXP x) {
3636
Storage::set__(x) ;
3737
}
38-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
38+
#if defined(HAS_VARIADIC_TEMPLATES)
3939
template <typename... T>
4040
DottedPair_Impl(const T&... args) {
4141
Storage::set__(pairlist(args...));

inst/include/Rcpp/Function.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ namespace Rcpp{
8282
return Rcpp_fast_eval(call, R_GlobalEnv);
8383
}
8484

85-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
85+
#if defined(HAS_VARIADIC_TEMPLATES)
8686
template <typename... T>
8787
SEXP operator()(const T&... args) const {
8888
return invoke(pairlist(args...), R_GlobalEnv);

inst/include/Rcpp/InternalFunctionWithStdFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#ifndef Rcpp_InternalFunctionWithStdFunction_h
2424
#define Rcpp_InternalFunctionWithStdFunction_h
2525

26-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
26+
#if defined(HAS_VARIADIC_TEMPLATES)
2727
#include <Rcpp/internal/call.h>
2828
#endif
2929
#include <functional>

inst/include/Rcpp/Language.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ namespace Rcpp{
102102
* 0.0 is wrapped as a numeric vector using wrap( const& double )
103103
* ...
104104
*/
105-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
105+
#if defined(HAS_VARIADIC_TEMPLATES)
106106
template <typename... T>
107107
Language_Impl(const std::string& symbol, const T&... t) {
108108
Storage::set__(pairlist(Rf_install(symbol.c_str()), t...) );

inst/include/Rcpp/Module.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ namespace Rcpp{
8686
#include <Rcpp/module/CppFunction.h>
8787
#include <Rcpp/module/get_return_type.h>
8888

89-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
89+
#if defined(HAS_VARIADIC_TEMPLATES)
9090
namespace Rcpp {
9191
template <typename RESULT_TYPE, typename... T>
9292
inline void signature(std::string& s, const char* name) {
@@ -112,6 +112,7 @@ namespace Rcpp {
112112
}
113113

114114
inline int nargs() { return sizeof...(T); }
115+
inline bool is_void() { return std::is_void<RESULT_TYPE>::value; }
115116
inline void signature(std::string& s, const char* name) { Rcpp::signature<RESULT_TYPE, T...>(s, name); }
116117
inline DL_FUNC get_function_ptr() { return (DL_FUNC)ptr_fun; }
117118

@@ -176,7 +177,7 @@ namespace Rcpp{
176177
private:
177178
ParentMethod* parent_method_pointer ;
178179
} ;
179-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
180+
#if defined(HAS_VARIADIC_TEMPLATES)
180181
template <typename... T>
181182
inline void ctor_signature(std::string& s, const std::string& classname) {
182183
s.assign(classname);
@@ -380,7 +381,7 @@ namespace Rcpp{
380381

381382
} ;
382383

383-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
384+
#if defined(HAS_VARIADIC_TEMPLATES)
384385
template <bool IsConst,typename Class, typename RESULT_TYPE, typename... T>
385386
class CppMethodImplN : public CppMethod<Class> {
386387
public:
@@ -428,7 +429,7 @@ namespace Rcpp{
428429
return call<decltype(f), CLEANED_RESULT_TYPE, T...>(f, args);
429430
}
430431
inline int nargs() { return sizeof...(T); }
431-
inline bool is_void() { return std::is_void<RESULT_TYPE>::value;}
432+
inline bool is_void() { return std::is_void<RESULT_TYPE>::value; }
432433
inline bool is_const() { return IsConst; }
433434
inline void signature(std::string& s, const char* name) { Rcpp::signature<RESULT_TYPE,T...>(s, name); }
434435
private:
@@ -551,7 +552,7 @@ namespace Rcpp{
551552
} ;
552553
}
553554

554-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
555+
#if defined(HAS_VARIADIC_TEMPLATES)
555556
namespace Rcpp {
556557
template <typename RESULT_TYPE, typename... T>
557558
void function(const char* name_, RESULT_TYPE (*fun)(T... t), const char* docstring = 0) {

inst/include/Rcpp/Pairlist.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace Rcpp{
4242
Pairlist_Impl(SEXP x){
4343
Storage::set__(r_cast<LISTSXP>(x)) ;
4444
}
45-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
45+
#if defined(HAS_VARIADIC_TEMPLATES)
4646
template <typename... T>
4747
Pairlist_Impl(const T&... args ){
4848
Storage::set__(pairlist(args... )) ;

inst/include/Rcpp/grow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ namespace Rcpp {
7070
return grow(Rf_mkString(head), y);
7171
}
7272

73-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
73+
#if defined(HAS_VARIADIC_TEMPLATES)
7474
template <typename T1>
7575
SEXP pairlist(const T1& t1) {
7676
return grow( t1, R_NilValue ) ;

inst/include/Rcpp/internal/call.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <Rcpp/traits/index_sequence.h>
55
#include <functional>
66

7-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
7+
#if defined(HAS_VARIADIC_TEMPLATES)
88

99
namespace Rcpp {
1010
namespace internal {
@@ -15,7 +15,7 @@ template <typename... T> struct type_pack {};
1515
/**
1616
* This specialisation is for functions that return a value, whereas the below
1717
* is for void-returning functions.
18-
*
18+
*
1919
* The "* = nullptr" default argument allows both templates to be well-defined
2020
* regardless of which one is used.
2121
*/
@@ -40,7 +40,7 @@ SEXP call_impl(const F& fun, SEXP* args, type_pack<RESULT_TYPE, Us...>,
4040
* Helper for calling a function with an array of SEXP arguments,
4141
* where each argument is converted to the appropriate type before being passed
4242
* to the function. A compile-time sequence is used to index the SEXP array.
43-
*
43+
*
4444
* The function only needs the intended types of the result and arguments,
4545
* which allows the template to be used for function pointers, lambdas, and
4646
* `std::function` objects.

inst/include/Rcpp/module/class.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
return constructor( docstring, valid ) ;
111111
}
112112

113-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
113+
#if defined(HAS_VARIADIC_TEMPLATES)
114114
template <typename... T>
115115
self& constructor( const char* docstring = 0, ValidConstructor valid = &yes_arity<sizeof...(T)> ){
116116
AddConstructor( new Constructor<Class,T...> , valid, docstring ) ;
@@ -265,7 +265,7 @@
265265
return *this ;
266266
}
267267

268-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
268+
#if defined(HAS_VARIADIC_TEMPLATES)
269269
template <typename RESULT_TYPE, typename... T>
270270
self& method(const char* name_, RESULT_TYPE (Class::*fun)(T...),
271271
const char* docstring = 0, ValidMethod valid = &yes_arity<sizeof...(T)>) {

inst/include/Rcpp/platform/compiler.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
#if __cplusplus >= 201103L
6969
#define RCPP_USING_CXX11
7070
#if __INTEL_COMPILER >= 1210
71-
// #define HAS_VARIADIC_TEMPLATES
71+
#define HAS_VARIADIC_TEMPLATES
7272
#endif
7373
#if __INTEL_COMPILER >= 1100
7474
#define HAS_STATIC_ASSERT
@@ -78,7 +78,7 @@
7878
#if __cplusplus >= 201103L
7979
#define RCPP_USING_CXX11
8080
#if __has_feature(cxx_variadic_templates)
81-
// #define HAS_VARIADIC_TEMPLATES
81+
#define HAS_VARIADIC_TEMPLATES
8282
#endif
8383
#if __has_feature(cxx_static_assert)
8484
#define HAS_STATIC_ASSERT
@@ -87,7 +87,7 @@
8787
#elif defined(__GNUC__)
8888
#ifdef __GXX_EXPERIMENTAL_CXX0X__
8989
#if GCC_VERSION >= 40300
90-
// #define HAS_VARIADIC_TEMPLATES
90+
#define HAS_VARIADIC_TEMPLATES
9191
#define HAS_STATIC_ASSERT
9292
#endif
9393
#endif

inst/include/Rcpp/traits/index_sequence.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define RCPP_TRAITS_INDEX_SEQUENCE_H
33

44

5-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
5+
#if defined(HAS_VARIADIC_TEMPLATES)
66

77
namespace Rcpp {
88
namespace traits {

inst/include/Rcpp/traits/named_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ template <typename T> struct is_named< named_object<T> > : public true_type {};
6666
template <> struct is_named< Rcpp::Argument > : public true_type {};
6767

6868

69-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
69+
#if defined(HAS_VARIADIC_TEMPLATES)
7070
template <typename... T> struct is_any_named : public false_type {};
7171
template <typename T> struct is_any_named<T> : public is_named<T>::type {};
7272

inst/include/Rcpp/vector/Vector.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ class Vector :
11221122
return Vector( 0 ) ;
11231123
}
11241124

1125-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
1125+
#if defined(HAS_VARIADIC_TEMPLATES)
11261126
public:
11271127
template <typename... T>
11281128
static Vector create(const T&... t){

inst/tinytest/test_module.R

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,25 @@ if( ! Rcpp:::capabilities()[["Rcpp modules"]] ) exit_file("Skipping as no Module
2222

2323
Rcpp::sourceCpp("cpp/Module.cpp")
2424

25+
# checks the presence of "invisible", added when the function returns void
26+
is_void <- function(call) {
27+
if (length(grep("invisible", deparse(call))) == 0)
28+
return(FALSE)
29+
return(TRUE)
30+
}
31+
2532
# test.Module <- function(){
2633
expect_equal( bar( 2L ), 4L )
2734
expect_equal( foo( 2L, 10.0 ), 20.0 )
2835
expect_equal( hello(), "hello" )
2936

37+
expect_false(is_void(bar@.Data))
38+
expect_false(is_void(foo@.Data))
39+
expect_false(is_void(hello@.Data))
40+
expect_true(is_void(bla@.Data))
41+
expect_true(is_void(bla1@.Data))
42+
expect_true(is_void(bla2@.Data))
43+
3044
w <- new( ModuleWorld )
3145
expect_equal( w$greet(), "hello" )
3246
w$set( "hello world" )
@@ -38,13 +52,24 @@ expect_equal( w$greet(), "hello world const ref" )
3852
w$clear( )
3953
expect_equal( w$greet(), "" )
4054

55+
expect_false(is_void(w$greet))
56+
expect_true(is_void(w$set))
57+
expect_true(is_void(w$set_ref))
58+
expect_true(is_void(w$set_const_ref))
59+
expect_true(is_void(w$clear))
60+
4161
# test.Module.exposed.class <- function(){
4262
test <- new( ModuleTest, 3.0 )
4363
expect_equal( Test_get_x_const_ref(test), 3.0 )
4464
expect_equal( Test_get_x_const_pointer(test), 3.0 )
4565
expect_equal( Test_get_x_ref(test), 3.0 )
4666
expect_equal( Test_get_x_pointer(test), 3.0 )
4767

68+
expect_false(is_void(Test_get_x_const_ref@.Data))
69+
expect_false(is_void(Test_get_x_const_pointer@.Data))
70+
expect_false(is_void(Test_get_x_ref@.Data))
71+
expect_false(is_void(Test_get_x_pointer@.Data))
72+
4873
expect_equal( attr_Test_get_x_const_ref(test), 3.0 )
4974
expect_equal( attr_Test_get_x_const_pointer(test), 3.0 )
5075
expect_equal( attr_Test_get_x_ref(test), 3.0 )

src/api.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ SEXP rcpp_capabilities() {
257257

258258
// [[Rcpp::internal]]
259259
SEXP rcpp_can_use_cxx0x() { // #nocov start
260-
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
260+
#if defined(HAS_VARIADIC_TEMPLATES)
261261
return Rf_ScalarLogical(TRUE);
262262
#else
263263
return Rf_ScalarLogical(FALSE);

0 commit comments

Comments
 (0)