[Rcpp-devel] any preprocessor expert around ?

Romain Francois romain at r-enthusiasts.com
Fri Apr 23 10:27:15 CEST 2010


Hello,

In the svn version of Rcpp (to be released soon) I have added some 
macros to facilitate writing functions in Rcpp.

The macros are RCPP_FUNCTION_0, RCPP_FUNCTION_1, ..., RCPP_FUNCTION_65 
(65 is the maximum number of arguments in a .Call call).

It goes like this :


RCPP_FUNCTION_3(int,foobar,
	int x, int y, NumericVector z){

	return x + y + z.size() ;
}


- The first argument of the macro is the type that is returned by the 
function body. This can be whatever Rcpp::wrap can handle, so int, 
double, Rcpp classes, STL classes, ...)

- The second argument is the name of the function

- The other arguments (3 arguments in this case because we use 
RCPP_FUNCTION_3) are arguments of the function. These can be anything 
that Rcpp::as can handle, so again any primitive type, SEXP, any Rcpp 
(new api) class, some STL classes, ...


Internally the macro expands to (slightly reformatted for the email):

int foobar__rcpp__wrapper__(int x, int y, NumericVector z) ;
extern "C" SEXP foobar(SEXP x0, SEXP x1, SEXP x2){
	SEXP res = R_NilValue ;
	try{
		res = ::Rcpp::wrap( foobar__rcpp__wrapper__(
			::Rcpp::internal::converter( x0 ),
			::Rcpp::internal::converter( x1 ),
			::Rcpp::internal::converter( x2 )) ) ;
	} catch( std::exception& __ex__ ){
		forward_exception_to_r( __ex__ ) ;
	} catch(...){
		::Rf_error( "c++ exception (unknown reason)" ) ;
	}
	return res ;
}
int foobar__rcpp__wrapper__(int x, int y, NumericVector z){
  return x + y + z.size() ;
}


The idea is that .Call expects a function that takes 0 or more SEXP and 
returns one SEXP, so the macro creates one : "foobar"

foobar then calls another function "foobar__rcpp__wrapper__" and takes 
care of:
- wraps the input SEXP in an Rcpp::internal::converter object. The 
converter class has a templated conversion operator that delegates to 
Rcpp::as :

		template <typename T> operator T(){
			return ::Rcpp::as<T>( x ) ;	
		}


- wraps the result back into a SEXP using Rcpp::wrap
- encloses the whole thing in an explicit try/catch/forward



The use of macros might be disrupting but the benefit is that this goes 
one step further in letter the developper express the code in terms of 
C++ rather than in terms of R data structures.

I'm using this e.g. in the highlight package  with a function that looks 
like this:

RCPP_FUNCTION_8(CharacterVector,get_highlighted_text,
	List data, int start, int end, std::string space,
	std::string newline, std::string prompt,
	std::string continuePrompt, bool initial_spaces ){
...
}


What sort of bothers me is the _3, _8 suffix. Does anyone have 
preprocessor tricks so that we could have for example a RCPP_FUNCTION 
macro counting the number of arguments and then doing the right thing.


There is also the RCPP_FUNCTION_NODECL_* macro that are identical except 
the first line is not included so that it can be included in a header file.

Romain


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/9aKDM9 : embed images in Rd documents
|- http://tr.im/OIXN : raster images and RImageJ
|- http://tr.im/OcQe : Rcpp 0.7.7



More information about the Rcpp-devel mailing list