I'm in the situation where I have an Rcpp::XPtr
to an Armadillo object (e.g. arma::Mat
, which may be a matrix of one of the supported data types). Now I'd like to write a function that queries the number of elements. The best I could come up with so far is the following (inspired by bigstatsr):
#define DISPATCH_DATA_TYPE(CALL) \
{ \
switch (data_type) \
{ \
case 1: CALL(unsigned short) \
case 2: CALL(unsigned int) \
case 3: CALL(unsigned long) \
case 4: CALL(short) \
case 5: CALL(int) \
case 6: CALL(long) \
case 7: CALL(float) \
case 8: CALL(double) \
default: throw Rcpp::exception("Unsupported data type."); \
} \
}
template <typename T>
arma::uword mat_length(SEXP mat)
{
Rcpp::XPtr< arma::Mat<T> > p(mat);
return p->n_elem;
}
#define MAT_LENGTH(TYPE) return mat_length<TYPE>(mat);
// [[Rcpp::export]]
arma::uword mat_length(SEXP mat, int data_type)
{
DISPATCH_DATA_TYPE(MAT_LENGTH)
}
Is there a better way of doing this? I'm using this pattern for quite a few functions and the verbosity is becoming a problem. Ideally I'd have a single but concise function, like (doesn't work of course)
arma::uword mat_length(SEXP mat)
{
Rcpp::XPtr<arma::Mat> p(mat);
return p->n_elem;
}
instead of two functions + a macro for every single instance where I pass an XPtr
like that from R to C.
Bonus question: is there anything obviously wrong with the macro-based approach? Is this somehow inefficient or could lead to problems down the line?
To create a reproducible example, add
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
// [[Rcpp::export]]
SEXP setup_mat(arma::uword n_rows, arma::uword n_cols)
{
arma::mat* res = new arma::mat(n_rows, n_cols);
return Rcpp::XPtr<arma::mat>(res);
}
and run Rcpp::sourceCpp()
on the file in R.