Skip to content

Variadic templates refinement #1336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
2024-10-07 Iñaki Ucar <[email protected]>

* inst/include/Rcpp/platform/compiler.h: Uncomment HAS_VARIADIC_TEMPLATES
macro definition
* src/api.cpp: Simplify checks for variadic templates
* inst/include/Rcpp/DataFrame.h: Idem
* inst/include/Rcpp/DottedPair.h: Idem
* inst/include/Rcpp/Function.h: Idem
* inst/include/Rcpp/InternalFunctionWithStdFunction.h: Idem
* inst/include/Rcpp/Language.h: Idem
* inst/include/Rcpp/Pairlist.h: Idem
* inst/include/Rcpp/grow.h: Idem
* inst/include/Rcpp/internal/call.h: Idem
* inst/include/Rcpp/module/class.h: Idem
* inst/include/Rcpp/traits/index_sequence.h: Idem
* inst/include/Rcpp/traits/named_object.h: Idem
* inst/include/Rcpp/vector/Vector.h: Idem
* inst/include/Rcpp/Module.h: Idem + add missing is_void method
* inst/tinytest/test_module.R: Add test for void functions and methods

2024-10-04 Dirk Eddelbuettel <[email protected]>

* DESCRIPTION (Version, Date): Roll micro version to 1.0.13.3
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/DataFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace Rcpp{
static DataFrame_Impl create(){
return DataFrame_Impl() ;
}
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename... T>
static DataFrame_Impl create(const T&... args) {
return DataFrame_Impl::from_list(Parent::create(args...));
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/DottedPair.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ RCPP_API_CLASS(DottedPair_Impl),
DottedPair_Impl(SEXP x) {
Storage::set__(x) ;
}
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename... T>
DottedPair_Impl(const T&... args) {
Storage::set__(pairlist(args...));
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace Rcpp{
return Rcpp_fast_eval(call, R_GlobalEnv);
}

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename... T>
SEXP operator()(const T&... args) const {
return invoke(pairlist(args...), R_GlobalEnv);
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/InternalFunctionWithStdFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#ifndef Rcpp_InternalFunctionWithStdFunction_h
#define Rcpp_InternalFunctionWithStdFunction_h

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
#include <Rcpp/internal/call.h>
#endif
#include <functional>
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ namespace Rcpp{
* 0.0 is wrapped as a numeric vector using wrap( const& double )
* ...
*/
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename... T>
Language_Impl(const std::string& symbol, const T&... t) {
Storage::set__(pairlist(Rf_install(symbol.c_str()), t...) );
Expand Down
11 changes: 6 additions & 5 deletions inst/include/Rcpp/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace Rcpp{
#include <Rcpp/module/CppFunction.h>
#include <Rcpp/module/get_return_type.h>

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

inline int nargs() { return sizeof...(T); }
inline bool is_void() { return std::is_void<RESULT_TYPE>::value; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch!

inline void signature(std::string& s, const char* name) { Rcpp::signature<RESULT_TYPE, T...>(s, name); }
inline DL_FUNC get_function_ptr() { return (DL_FUNC)ptr_fun; }

Expand Down Expand Up @@ -176,7 +177,7 @@ namespace Rcpp{
private:
ParentMethod* parent_method_pointer ;
} ;
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename... T>
inline void ctor_signature(std::string& s, const std::string& classname) {
s.assign(classname);
Expand Down Expand Up @@ -380,7 +381,7 @@ namespace Rcpp{

} ;

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <bool IsConst,typename Class, typename RESULT_TYPE, typename... T>
class CppMethodImplN : public CppMethod<Class> {
public:
Expand Down Expand Up @@ -428,7 +429,7 @@ namespace Rcpp{
return call<decltype(f), CLEANED_RESULT_TYPE, T...>(f, args);
}
inline int nargs() { return sizeof...(T); }
inline bool is_void() { return std::is_void<RESULT_TYPE>::value;}
inline bool is_void() { return std::is_void<RESULT_TYPE>::value; }
inline bool is_const() { return IsConst; }
inline void signature(std::string& s, const char* name) { Rcpp::signature<RESULT_TYPE,T...>(s, name); }
private:
Expand Down Expand Up @@ -551,7 +552,7 @@ namespace Rcpp{
} ;
}

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
namespace Rcpp {
template <typename RESULT_TYPE, typename... T>
void function(const char* name_, RESULT_TYPE (*fun)(T... t), const char* docstring = 0) {
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/Pairlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace Rcpp{
Pairlist_Impl(SEXP x){
Storage::set__(r_cast<LISTSXP>(x)) ;
}
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename... T>
Pairlist_Impl(const T&... args ){
Storage::set__(pairlist(args... )) ;
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/grow.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace Rcpp {
return grow(Rf_mkString(head), y);
}

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename T1>
SEXP pairlist(const T1& t1) {
return grow( t1, R_NilValue ) ;
Expand Down
6 changes: 3 additions & 3 deletions inst/include/Rcpp/internal/call.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <Rcpp/traits/index_sequence.h>
#include <functional>

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)

namespace Rcpp {
namespace internal {
Expand All @@ -15,7 +15,7 @@ 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.
*/
Expand All @@ -40,7 +40,7 @@ SEXP call_impl(const F& fun, SEXP* args, type_pack<RESULT_TYPE, Us...>,
* 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.
Expand Down
4 changes: 2 additions & 2 deletions inst/include/Rcpp/module/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
return constructor( docstring, valid ) ;
}

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

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
template <typename RESULT_TYPE, typename... T>
self& method(const char* name_, RESULT_TYPE (Class::*fun)(T...),
const char* docstring = 0, ValidMethod valid = &yes_arity<sizeof...(T)>) {
Expand Down
6 changes: 3 additions & 3 deletions inst/include/Rcpp/platform/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
#if __cplusplus >= 201103L
#define RCPP_USING_CXX11
#if __INTEL_COMPILER >= 1210
// #define HAS_VARIADIC_TEMPLATES
#define HAS_VARIADIC_TEMPLATES
#endif
#if __INTEL_COMPILER >= 1100
#define HAS_STATIC_ASSERT
Expand All @@ -78,7 +78,7 @@
#if __cplusplus >= 201103L
#define RCPP_USING_CXX11
#if __has_feature(cxx_variadic_templates)
// #define HAS_VARIADIC_TEMPLATES
#define HAS_VARIADIC_TEMPLATES
#endif
#if __has_feature(cxx_static_assert)
#define HAS_STATIC_ASSERT
Expand All @@ -87,7 +87,7 @@
#elif defined(__GNUC__)
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#if GCC_VERSION >= 40300
// #define HAS_VARIADIC_TEMPLATES
#define HAS_VARIADIC_TEMPLATES
#define HAS_STATIC_ASSERT
#endif
#endif
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/traits/index_sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define RCPP_TRAITS_INDEX_SEQUENCE_H


#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)

namespace Rcpp {
namespace traits {
Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/traits/named_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ template <typename T> struct is_named< named_object<T> > : public true_type {};
template <> struct is_named< Rcpp::Argument > : public true_type {};


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

Expand Down
2 changes: 1 addition & 1 deletion inst/include/Rcpp/vector/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ class Vector :
return Vector( 0 ) ;
}

#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
public:
template <typename... T>
static Vector create(const T&... t){
Expand Down
25 changes: 25 additions & 0 deletions inst/tinytest/test_module.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,25 @@ if( ! Rcpp:::capabilities()[["Rcpp modules"]] ) exit_file("Skipping as no Module

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

# checks the presence of "invisible", added when the function returns void
is_void <- function(call) {
if (length(grep("invisible", deparse(call))) == 0)
return(FALSE)
return(TRUE)
}

# test.Module <- function(){
expect_equal( bar( 2L ), 4L )
expect_equal( foo( 2L, 10.0 ), 20.0 )
expect_equal( hello(), "hello" )

expect_false(is_void([email protected]))
expect_false(is_void([email protected]))
expect_false(is_void([email protected]))
expect_true(is_void([email protected]))
expect_true(is_void([email protected]))
expect_true(is_void([email protected]))

w <- new( ModuleWorld )
expect_equal( w$greet(), "hello" )
w$set( "hello world" )
Expand All @@ -38,13 +52,24 @@ expect_equal( w$greet(), "hello world const ref" )
w$clear( )
expect_equal( w$greet(), "" )

expect_false(is_void(w$greet))
expect_true(is_void(w$set))
expect_true(is_void(w$set_ref))
expect_true(is_void(w$set_const_ref))
expect_true(is_void(w$clear))

# test.Module.exposed.class <- function(){
test <- new( ModuleTest, 3.0 )
expect_equal( Test_get_x_const_ref(test), 3.0 )
expect_equal( Test_get_x_const_pointer(test), 3.0 )
expect_equal( Test_get_x_ref(test), 3.0 )
expect_equal( Test_get_x_pointer(test), 3.0 )

expect_false(is_void([email protected]))
expect_false(is_void([email protected]))
expect_false(is_void([email protected]))
expect_false(is_void([email protected]))

expect_equal( attr_Test_get_x_const_ref(test), 3.0 )
expect_equal( attr_Test_get_x_const_pointer(test), 3.0 )
expect_equal( attr_Test_get_x_ref(test), 3.0 )
Expand Down
2 changes: 1 addition & 1 deletion src/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ SEXP rcpp_capabilities() {

// [[Rcpp::internal]]
SEXP rcpp_can_use_cxx0x() { // #nocov start
#if defined(HAS_VARIADIC_TEMPLATES) || defined(RCPP_USING_CXX11)
#if defined(HAS_VARIADIC_TEMPLATES)
return Rf_ScalarLogical(TRUE);
#else
return Rf_ScalarLogical(FALSE);
Expand Down
Loading