Extending wrap with Rcpp11

[This article was first published on R Enthusiast and R/C++ hero, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

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 their blog: R Enthusiast and R/C++ hero.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)