Extending wrap with Rcpp11

May 22, 2014
By

(This article was first published on R Enthusiast and R/C++ hero, and kindly contributed to R-bloggers)

Context

Extending wrap to custom classes has always been a struggle in Rcpp, and led to the split between RcppCommon.h and Rcpp.h, the idea being that you load a "minimal" subset of Rcpp, declare your class, declare that you are going to provide a specialization of wrap, load the rest of Rcpp (the meat), and finally define your specialization.

Let's consider this template class :

template <typename T>  
class MyType {} ;  

it does nothing, I'm just using it to illustrate the point. Extending wrap for such a template will allow us to write functions like this:

// [[Rcpp::export]]
MyType<double> test(){  
  return MyType<double>() ;
}

Attributes will generate code that uses wrap internally. So all we have to do is write this special wrap. The simplest way is for classes that have an operator SEXP but for the purpose of this post, let's just consider it does not and that we can't make modifications to the class.

implement wrap with Rcpp

In Rcpp, here is what it takes to implement wrap for it (according to the extending vignette).

// first include the minimal set of Rcpp functionality
#include <RcppCommon.h>

// declare our type
template <typename T>  
class MyType {} ;

// declare that we will later specialize wrap
namespace Rcpp{

    template <typename T>
    inline SEXP wrap( const MyType<T>& obj ) ;

} 

// include the rest
#include <Rcpp.h>

// and finally define the overload
namespace Rcpp{  
    template <typename T>
    inline SEXP wrap( const MyType<T>& obj ) {
        return IntegerVector::create( 1, 2 ) ;        
    }
}

This has been the basis for packages like RcppArmadillo, etc ... and it requires lots of care. The definition of our wrap must be after we include Rcpp.h because we need IntegerVector::create, inclusion of Rcpp.h so that all uses of wrap know about our specialization, the declaration of our specialization must be after RcppCommon.h because that's where we declare the general wrap.

That's a lot to stomach.

implement wrap in Rcpp11

In Rcpp11 the RcppCommon.h does not exist and specializing wrap is simpler:

// include all Rcpp11 headers all at once
#include <Rcpp.h>

// our template class
template <typename T>  
class MyType {} ;

// specialization of the Wrapper template for it. 
namespace Rcpp{

    template <typename T>
    struct Wrapper< MyType<T> > {
        static inline SEXP wrap( const MyType<T>& obj ){
            return IntegerVector::create( 1, 2 ) ;    
        }
    } ;
} 

All we have to do is write specializations of the Wrapper template class. This is much simpler.

To leave a comment for the author, please follow the link and comment on his blog: R Enthusiast and R/C++ hero.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.