0% found this document useful (0 votes)
24 views3 pages

RCPP Extending

This document provides an overview of extending Rcpp to work with user-defined C++ types by specializing the Rcpp::wrap and Rcpp::as functions. There are intrusive and non-intrusive ways to extend both Rcpp::wrap and Rcpp::as. Intrusively, a type can implement an operator SEXP to enable conversion via Rcpp::wrap, or the programmer can specialize the Rcpp::wrap and Rcpp::as templates. Non-intrusively, the programmer can specialize just the Rcpp::wrap or Rcpp::as templates without modifying the third-party types. Templates can be partially specialized as well.

Uploaded by

David Moro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views3 pages

RCPP Extending

This document provides an overview of extending Rcpp to work with user-defined C++ types by specializing the Rcpp::wrap and Rcpp::as functions. There are intrusive and non-intrusive ways to extend both Rcpp::wrap and Rcpp::as. Intrusively, a type can implement an operator SEXP to enable conversion via Rcpp::wrap, or the programmer can specialize the Rcpp::wrap and Rcpp::as templates. Non-intrusively, the programmer can specialize just the Rcpp::wrap or Rcpp::as templates without modifying the third-party types. Templates can be partially specialized as well.

Uploaded by

David Moro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

Rcpp Extending

Dirk Eddelbuettela and Romain Françoisb


a
http://dirk.eddelbuettel.com; b https://romain.rbind.io/

This version was compiled on September 24, 2017

This note provides an overview of the steps programmers should follow to # [1] 10
extend Rcpp (Eddelbuettel et al., 2017a; Eddelbuettel and François, 2011)
for use with their own classes. This document is based on our expe- The Rcpp converter function Rcpp::as and Rcpp::wrap have
rience in extending Rcpp to work with the Armadillo (Sanderson, 2010) been designed to be extensible to user-defined types and third-party
classes, available in the separate package RcppArmadillo (Eddelbuettel types.
et al., 2017b). This document assumes knowledge of Rcpp as well as
some knowledge of C++ templates (Abrahams and Gurtovoy, 2004). 2. Extending Rcpp::wrap

Rcpp | extending | R | C++ The Rcpp::wrap converter is extensible in essentially two ways :
intrusive and non-intrusive.
1. Introduction 2.1. Intrusive extension. When extending Rcpp with your own
Rcpp facilitates data interchange between R and C++ through the data type, the recommended way is to implement a conversion to
templated functions Rcpp::as (for conversion of objects from R SEXP. This lets Rcpp::wrap know about the new data type. The
to C++) and Rcpp::wrap (for conversion from C++ to R). In other template meta programming (or TMP) dispatch is able to recognize
words, we convert between the so-called S-expression pointers (in that a type is convertible to a SEXP and Rcpp::wrap will use that
type SEXP) to a templated C++ type, and vice versa. The corre- conversion.
sponding function declarations are as follows: The caveat is that the type must be declared before the main
header file Rcpp.h is included.
// conversion from R to C++
template <typename T> T as(SEXP x); #include <RcppCommon.h>

// conversion from C++ to R class Foo {


template <typename T> SEXP wrap(const T& object); public:
Foo();
These converters are often used implicitly, as in the following
code chunk: // this operator enables implicit Rcpp::wrap
operator SEXP();
#include <Rcpp.h> }
using namespace Rcpp;
#include <Rcpp.h>
// [[Rcpp::export]]
List fx(List input) { // we get a list from R
This is called intrusive because the conversion to SEXP operator
// pull std::vector<double> from R list
has to be declared within the class.
// this is achieved through an implicit
// call to Rcpp::as 2.2. Non-intrusive extension. It is often desirable to offer auto-
std::vector<double> x = input["x"]; matic conversion to third-party types, over which the developer
has no control and can therefore not include a conversion to SEXP
// return an R list; this is achieved operator in the class definition.
// through an implicit call to Rcpp::wrap To provide automatic conversion from C++ to R, one must de-
return List::create(_["front"] = x.front(), clare a specialization of the Rcpp::wrap template between the
_["back"] = x.back()); includes of RcppCommon.h and Rcpp.h.
}
#include <RcppCommon.h>
Example:
// third party library that declares class Bar
## Run sourceCpp compilation to include file
#include <foobar.h>
# Rcpp::sourceCpp(file= "code.cpp")
input <- list( x = seq(1, 10, by = 0.5) )
// declaring the specialization
fx(input)
namespace Rcpp {
template <> SEXP wrap(const Bar&);
# $front }
# [1] 1
# // this must appear after the specialization,
# $back // otherwise the specialization will not be

https://cran.r-project.org/package=Rcpp Rcpp Vignette | September 24, 2017 | 1–3


// seen by Rcpp types #include <Rcpp.h>
#include <Rcpp.h>
It should be noted that only the declaration is required. The 3.2. Non-intrusive extension. It is also possible to fully specialize
implementation can appear after the Rcpp.h file is included, and Rcpp::as to enable non-intrusive implicit conversion capabilities.
therefore take full advantage of the Rcpp type system. #include <RcppCommon.h>
Another non-intrusive option is to expose an external pointer.
The macro RCPP_EXPORT_WRAP provides an easy way to expose a // third party library that declares class Bar
C++ class to R as an external pointer. It can be used instead of
#include <foobar.h>
specializing Rcpp::wrap, and should not be used simultaneously.
#include RcppCommon.h // declaring the specialization
#include foobar.h namespace Rcpp {
template <> Bar as(SEXP);
RCPP_EXPORT_WRAP(Bar); }

// this must appear after the specialization, or


2.3. Templates and partial specialization. It is perfectly valid to
// specialization will not be seen by Rcpp types
declare a partial specialization for the Rcpp::wrap template. The
#include <Rcpp.h>
compiler will identify the appropriate overload:
#include <RcppCommon.h> Furthermore, another non-intrusive option is to opt for sharing
an R external pointer. The macro RCPP_EXPORT_AS provides an
// third party library that declares easy way to extend Rcpp::as to expose R external pointers to C++.
// a template class Bling<T> It can be used instead of specializing Rcpp::as, and should not be
#include <foobar.h> used simultaneously.

// declaring the partial specialization #include RcppCommon.h


namespace Rcpp { #include foobar.h
namespace traits {
RCPP_EXPORT_AS(Bar);
template <typename T>
SEXP wrap(const Bling<T>&); With this being said, there is one additional macro that
can be used to simultaneously define both Rcpp::wrap and
} Rcpp::as specialization for an external pointer. The macro
} RCPP_EXPOSED_CLASS can be use to transparently exchange a class
between R and C++ as an external pointer. Do not simultane-
// this must appear after the specialization, or ously use it alongside RCPP_EXPOSED_AS, RCPP_EXPOSED_WRAP,
// specialization will not be seen by Rcpp types Rcpp::wrap, or Rcpp::as.
#include <Rcpp.h>
3.3. Templates and partial specialization. The signature of
Rcpp::as does not allow partial specialization. When expos-
3. Extending Rcpp::as ing a templated class to Rcpp::as, the programmer must spe-
Conversion from R to C++ is also possible in both intrusive and cialize the Rcpp::traits::Exporter template class. The TMP dis-
non-intrusive ways. patch will recognize that a specialization of Exporter is avail-
able and delegate the conversion to this class. Rcpp defines the
3.1. Intrusive extension. As part of its template meta programming Rcpp::traits::Exporter template class as follows :
dispatch logic, Rcpp::as will attempt to use the constructor of the
namespace Rcpp {
target class taking a SEXP.
namespace traits {
#include <RcppCommon.h>
template <typename T> class Exporter{
class Foo{ public:
public: Exporter(SEXP x) : t(x){}
Foo(); inline T get() { return t; }

// this ctor enables implicit Rcpp::as private:


Foo(SEXP); T t;
} };
}
}
// this must appear after the specialization, or
// specialization will not be seen by Rcpp types This is the reason why the default behavior of Rcpp::as is to
invoke the constructor of the type T taking a SEXP.

2 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


Since partial specialization of class templates is allowed, we can Using this approach, the requirements for the Exporter<
expose a set of classes as follows: Bling<T> > class are:
#include <RcppCommon.h> • it should have a constructor taking a SEXP
• it should have a methods called get that returns an instance
// third party library that declares of the Bling<T> type.
// a template class Bling<T>
#include <foobar.h>
4. Summary
// declaring the partial specialization The Rcpp package greatly facilitates the transfer of objects between
namespace Rcpp { R and C++. This note has shown how to extend Rcpp to either user-
namespace traits { defined or third-party classes via the Rcpp::as and Rcpp::wrap
template <typename T> template functions. Both intrusive and non-intrusive approaches
class Exporter< Bling<T> >; were discussed.
}
}

// this must appear after the specialization, or


// specialization will not be seen by Rcpp types
#include <Rcpp.h>
References 0.12.12, URL http://CRAN.R-Project.org/package=Rcpp.
Eddelbuettel D, François R, Bates D, Ni B (2017b). RcppArmadillo: Rcpp
Abrahams D, Gurtovoy A (2004). C++ Template Metaprogramming: Concepts,
integration for Armadillo templated linear algebra library. R package version
Tools and Techniques from Boost and Beyond. Addison-Wesley, Boston.
0.7.960.1.2, URL http://CRAN.R-Project.org/package=RcppArmadillo.
Eddelbuettel D, François R (2011). “Rcpp: Seamless R and C++ Integration.”
Sanderson C (2010). “Armadillo: An open source C++ Algebra Library for Fast
Journal of Statistical Software, 40(8), 1–18. URL http://www.jstatsoft.org/v40/
Prototyping and Computationally Intensive Experiments.” Technical report,
i08/.
NICTA. URL http://arma.sf.net.
Eddelbuettel D, François R, Allaire J, Ushey K, Kou Q, Russel N, Chambers J,
Bates D (2017a). Rcpp: Seamless R and C++ Integration. R package version

Eddelbuettel and François Rcpp Vignette | September 24, 2017 | 3

You might also like