[Rcpp-commits] r4527 - in pkg/Rcpp: . vignettes
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Sep 21 17:23:37 CEST 2013
Author: edd
Date: 2013-09-21 17:23:36 +0200 (Sat, 21 Sep 2013)
New Revision: 4527
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/vignettes/Rcpp-modules.Rnw
Log:
Remove local compilations from Rcpp-modules vignette -- package now passes win-builder
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2013-09-20 19:12:57 UTC (rev 4526)
+++ pkg/Rcpp/ChangeLog 2013-09-21 15:23:36 UTC (rev 4527)
@@ -1,3 +1,9 @@
+2013-09-21 Dirk Eddelbuettel <edd at debian.org>
+
+ * vignettes/Rcpp-modules.Rnw: Remove vignette-local compilations
+ which again caused problems for the Windows builds at R-Forge and
+ win-builder. Unit tests comprise the same functionality and pass.
+
2013-09-20 Dirk Eddelbuettel <edd at debian.org>
* R/Module.R: More ':::' cleanups to make R CMD check happy
Modified: pkg/Rcpp/vignettes/Rcpp-modules.Rnw
===================================================================
--- pkg/Rcpp/vignettes/Rcpp-modules.Rnw 2013-09-20 19:12:57 UTC (rev 4526)
+++ pkg/Rcpp/vignettes/Rcpp-modules.Rnw 2013-09-21 15:23:36 UTC (rev 4527)
@@ -21,8 +21,7 @@
\newcommand{\pkg}[1]{{\fontseries{b}\selectfont #1}}
<<echo=FALSE,print=FALSE>>=
-require( inline )
-require( Rcpp )
+suppressMessages(require(Rcpp))
prettyVersion <- packageDescription("Rcpp")$Version
prettyDate <- format(Sys.Date(), "%B %e, %Y")
@
@@ -31,27 +30,6 @@
\title{Exposing \proglang{C++} functions and classes with \pkg{Rcpp} modules}
\date{\pkg{Rcpp} version \Sexpr{prettyVersion} as of \Sexpr{prettyDate}}
-<<echo=FALSE>>=
-link <- function( f, package, text = f, root = "http://finzi.psych.upenn.edu/R/library/" ) {
- h <- if( missing(package) ) {
- as.character( help( f ) )
- } else {
- as.character( help( f, package = paste( package, sep = "" ) ) )
- }
- if( ! length(h) ) {
- sprintf( "\\\\textbf{%s}", f )
- } else {
- rx <- "^.*/([^/]*?)/help/(.*?)$"
- package <- sub( rx, "\\1", h, perl = TRUE )
- page <- sub( rx, "\\2", h, perl = TRUE )
- sprintf( "\\\\href{%s%s/html/%s.html}{\\\\texttt{%s}}", root, package, page, text )
- }
-}
-linkS4class <- function( cl, package, text = cl, root = "http://finzi.psych.upenn.edu/R/library/" ) {
- link( sprintf("%s-class", cl), package, text, root )
-}
-@
-
\begin{document}
\maketitle
@@ -78,7 +56,7 @@
These \pkg{Rcpp} facilities offer a lot of assistance to the programmer
wishing to interface \proglang{R} and \proglang{C++}. At the same time, these
facilities are limited as they operate on a function-by-function basis. The
-programmer has to implement a \Sexpr{link(".Call")} compatible function (to
+programmer has to implement a \code{.Call} compatible function (to
conform to the \proglang{R} API) using classes of the \pkg{Rcpp} API as
described in the next section.
@@ -127,6 +105,24 @@
provides a much more elegant and unintrusive way to expose \proglang{C++}
functions such as the \texttt{norm} function shown above to \proglang{R}.
+We should note that \pkg{Rcpp} now has \textsl{Rcpp attributes} which extends
+certain aspect of \textsl{Rcpp modules} and makes binding to simple functions
+such as this one even easier. With \textsl{Rcpp attribues} we can just write
+
+<<lang=cpp>>=
+# include <Rcpp.h>
+
+// [[Rcpp::export]]
+double norm(double x, double y) {
+ return sqrt(x*x + y*y);
+}
+@
+
+See the corresponding vignette \citep{CRAN:Rcpp:Attributes} for details, but
+read on for \textsl{Rcpp modules} which contains to provide features not
+covered by \textsl{Rcpp attributes}, particularly when it comes to binding
+entire C++ classes and more.
+
\subsection{Exposing classes using Rcpp}
Exposing \proglang{C++} classes or structs is even more of a challenge because it
@@ -191,57 +187,22 @@
they usually get wrapped as a slot of an S4 class.
Using \code{cxxfunction()} from the \pkg{inline} package, we can build this
-example on the fly:
+example on the fly. Suppose the previous example code assigned to a text variable
+\texttt{unifModcode}, we could then do
-<<>>=
-f1 <- cxxfunction( , "", includes = '
-using namespace Rcpp;
-
-class Uniform {
-public:
- Uniform(double min_, double max_) : min(min_), max(max_) {}
-
- NumericVector draw(int n) {
- RNGScope scope;
- return runif( n, min, max );
- }
-
-private:
- double min, max;
-};
-
-/// create an external pointer to a Uniform object
-RcppExport SEXP Uniform__new(SEXP min_, SEXP max_) {
- // convert inputs to appropriate C++ types
- double min = as<double>(min_), max = as<double>(max_);
-
- // create a pointer to an Uniform object and wrap it
- // as an external pointer
- Rcpp::XPtr<Uniform> ptr( new Uniform( min, max ), true );
-
- // return the external pointer to the R side
- return ptr;
-}
-
-/// invoke the draw method
-RcppExport SEXP Uniform__draw( SEXP xp, SEXP n_ ) {
- // grab the object as a XPtr (smart pointer) to Uniform
- Rcpp::XPtr<Uniform> ptr(xp);
-
- // convert the parameter to int
- int n = as<int>(n_);
-
- // invoke the function
- NumericVector res = ptr->draw( n );
-
- // return the result to R
- return res;
-}
-', plugin = "Rcpp" )
-getDynLib( f1 )
+%% DE 21 Sep 2013: there must a bug somewhere in the vignette processing
+%% as the following example produces only empty lines preceded
+%% by '+' -- same for 0.10.4 release and current 0.10.5 pre-release
+%% hence shortened example to not show code again
+<<eval=FALSE>>=
+f1 <- cxxfunction( , "", includes = unifModCode, plugin = "Rcpp" )
+getDynLib(f1) ## will display information about 'f1' just created
@
-<<>>=
+The following listing shows some \textsl{manual} wrapping to access the code,
+we will see later how this can be automated:
+
+<<eval=FALSE>>=
setClass( "Uniform", representation( pointer = "externalptr" ) )
# helper
@@ -309,9 +270,9 @@
the need for a wrapper function using either \pkg{Rcpp} or the \proglang{R} API.
On the \proglang{R} side, the module is retrieved by using the
-\Sexpr{link("Module")} function from \pkg{Rcpp}
+\code{Module} function from \pkg{Rcpp}
-<<>>=
+<<eval=FALSE>>=
inc <- '
using namespace Rcpp;
@@ -325,8 +286,7 @@
'
fx <- cxxfunction(signature(), plugin="Rcpp", include=inc)
-mod <- Module( "mod", getDynLib(fx) )
-mod$norm( 3, 4 )
+mod <- Module("mod", getDynLib(fx))
@
Note that this example assumed that the previous code segment defining the
@@ -380,12 +340,12 @@
RCPP_MODULE(yada) {
using namespace Rcpp;
- function( "hello" , &hello );
- function( "bar" , &bar );
- function( "foo" , &foo );
- function( "bla" , &bla );
- function( "bla1" , &bla1 );
- function( "bla2" , &bla2 );
+ function("hello" , &hello);
+ function("bar" , &bar );
+ function("foo" , &foo );
+ function("bla" , &bla );
+ function("bla1" , &bla1 );
+ function("bla2" , &bla2 );
}
@
@@ -394,13 +354,13 @@
<<eval=FALSE>>=
require( Rcpp )
-yd <- Module( "yada", getDynLib(fx) )
-yd$bar( 2L )
-yd$foo( 2L, 10.0 )
+yd <- Module("yada", getDynLib(fx))
+yd$bar(2L)
+yd$foo(2L, 10.0)
yd$hello()
yd$bla()
-yd$bla1( 2L)
-yd$bla2( 2L, 5.0 )
+yd$bla1(2L)
+yd$bla2(2L, 5.0)
@
In the case of a package (as for example the one created by
@@ -408,14 +368,14 @@
below), we can use
<<eval=FALSE>>=
-require( myModulePackage ) ## or whichever name was chose
+require(myModulePackage) ## or whichever name was chose
-bar( 2L )
-foo( 2L, 10.0 )
+bar(2L)
+foo(2L, 10.0)
hello()
bla()
-bla1( 2L)
-bla2( 2L, 5.0 )
+bla1(2L)
+bla2(2L, 5.0)
@
@@ -452,24 +412,10 @@
The description is used when displaying the function to the R prompt:
-<<echo=FALSE>>=
-fx <- cxxfunction( , "", includes = '
-
-using namespace Rcpp;
-
-double norm( double x, double y ) {
- return sqrt( x*x + y*y );
-}
-
-RCPP_MODULE(mod) {
- function( "norm", &norm, "Provides a simple vector norm" );
-}
-', plugin = "Rcpp" )
+<<eval=FALSE>>=
+mod <- Module("mod", getDynLib(fx))
+show(mod$norm)
@
-<<>>=
-mod <- Module( "mod", getDynLib( fx ) )
-show( mod$norm )
-@
\subsubsection{Formal arguments specification}
@@ -494,23 +440,7 @@
A simple usage example is provided below:
-<<echo=FALSE,results=hide>>=
-fx_form <- cxxfunction( , '', includes = '
-using namespace Rcpp;
-
-double norm( double x, double y ) {
- return sqrt( x*x + y*y );
-}
-
-RCPP_MODULE(mod_formals) {
- function("norm", &norm,
- List::create( _["x"] = 0.0, _["y"] = 0.0 ),
- "Provides a simple vector norm");
-}
-', plugin = "Rcpp" )
-mod <- Module( "mod_formals", getDynLib( fx_form ), mustStart = TRUE )
-@
-<<>>=
+<<eval=FALSE>>=
norm <- mod$norm
norm()
norm( y = 2 )
@@ -536,25 +466,9 @@
This can be used as follows:
-<<echo=FALSE,results=hide>>=
-fx_form2 <- cxxfunction( , '', includes = '
-using namespace Rcpp;
-
-double norm( double x, double y ) {
- return sqrt( x*x + y*y );
-}
-
-RCPP_MODULE(mod_formals2) {
- function("norm", &norm,
- List::create( _["x"], _["y"] = 0.0 ),
- "Provides a simple vector norm");
-}
-', plugin = "Rcpp" )
-mod <- Module( "mod_formals2", getDynLib( fx_form2 ), mustStart = TRUE )
-@
-<<>>=
+<<eval=FALSE>>=
norm <- mod$norm
-args( norm )
+args(norm)
@
The ellipsis (\texttt{...}) can be used to denote that additional arguments
@@ -573,23 +487,7 @@
"documentation for norm");
}
@
-<<echo=FALSE,results=hide>>=
-fx_form3 <- cxxfunction( , '', includes = '
-using namespace Rcpp;
-
-double norm( double x, double y ) {
- return sqrt( x*x + y*y );
-}
-
-RCPP_MODULE(mod_formals3) {
- function( "norm", &norm,
- List::create( _["x"] , _["..."] ),
- "documentation for norm");
-}
-', plugin = "Rcpp" )
-mod <- Module( "mod_formals3", getDynLib( fx_form3 ), mustStart = TRUE )
-@
-<<>>=
+<<eval=FALSE>>=
norm <- mod$norm
args( norm )
@
@@ -639,42 +537,7 @@
}
@
-<<results=hide,echo=FALSE>>=
-fx_unif <- cxxfunction( , "", includes = '
-using namespace Rcpp;
-class Uniform {
-public:
- Uniform(double min_, double max_) : min(min_), max(max_) {}
-
- NumericVector draw(int n) const {
- RNGScope scope;
- return runif( n, min, max );
- }
-
- double min, max;
-};
-
-double uniformRange( Uniform* w) {
- return w->max - w->min;
-}
-
-RCPP_MODULE(unif_module) {
-
- class_<Uniform>( "Uniform" )
-
- .constructor<double,double>()
-
- .field( "min", &Uniform::min )
- .field( "max", &Uniform::max )
-
- .method( "draw", &Uniform::draw )
- .method( "range", &uniformRange )
- ;
-
-}
-', plugin = "Rcpp" )
-@
-<<>>=
+<<eval=FALSE>>=
## assumes fx_unif <- cxxfunction(...) has ben run
unif_module <- Module( "unif_module", getDynLib(fx_unif ) )
Uniform <- unif_module$Uniform
@@ -848,46 +711,7 @@
Here is a simple usage example:
-<<echo=FALSE,results=hide>>=
-fx_bar <- cxxfunction( , "", includes = '
-class Bar {
-public:
-
- Bar(double x_) : x(x_), nread(0), nwrite(0) {}
-
- double get_x( ) {
- nread++;
- return x;
- }
-
- void set_x( double x_) {
- nwrite++;
- x = x_;
- }
-
- IntegerVector stats() const {
- return IntegerVector::create(_["read"] = nread,
- _["write"] = nwrite);
- }
-
-private:
- double x;
- int nread, nwrite;
-};
-
-RCPP_MODULE(mod_bar) {
- class_<Bar>( "Bar" )
-
- .constructor<double>()
-
- .property( "x", &Bar::get_x, &Bar::set_x )
- .method( "stats", &Bar::stats )
- ;
-}
-', plugin = "Rcpp" )
-mod_bar <- Module( "mod_bar", getDynLib( fx_bar ) )
-@
-<<>>=
+<<eval=FALSE>>=
Bar <- mod_bar$Bar
b <- new( Bar, 10 )
b$x + b$x
@@ -1037,71 +861,7 @@
}
@
-<<echo=FALSE,results=hide>>=
-fx_vec <- cxxfunction(, '', includes = '
-// convenience typedef
-typedef std::vector<double> vec;
-
-// helpers
-void vec_assign( vec* obj, Rcpp::NumericVector data ) {
- obj->assign( data.begin(), data.end() );
-}
-
-void vec_insert( vec* obj, int position, Rcpp::NumericVector data) {
- vec::iterator it = obj->begin() + position;
- obj->insert( it, data.begin(), data.end() );
-}
-
-Rcpp::NumericVector vec_asR( vec* obj ) {
- return Rcpp::wrap( *obj );
-}
-
-void vec_set( vec* obj, int i, double value ) {
- obj->at( i ) = value;
-}
-
-RCPP_MODULE(mod_vec) {
- using namespace Rcpp;
-
- // we expose the class std::vector<double> as "vec" on the R side
- class_<vec>( "vec")
-
- // exposing constructors
- .constructor()
- .constructor<int>()
-
- // exposing member functions
- .method( "size", &vec::size)
- .method( "max_size", &vec::max_size)
- .method( "resize", &vec::resize)
- .method( "capacity", &vec::capacity)
- .method( "empty", &vec::empty)
- .method( "reserve", &vec::reserve)
- .method( "push_back", &vec::push_back )
- .method( "pop_back", &vec::pop_back )
- .method( "clear", &vec::clear )
-
- // specifically exposing const member functions
- .const_method( "back", &vec::back )
- .const_method( "front", &vec::front )
- .const_method( "at", &vec::at )
-
- // exposing free functions taking a std::vector<double>*
- // as their first argument
- .method( "assign", &vec_assign )
- .method( "insert", &vec_insert )
- .method( "as.vector", &vec_asR )
-
- // special methods for indexing
- .const_method( "[[", &vec::at )
- .method( "[[<-", &vec_set )
-
- ;
-}
-', plugin = "Rcpp" )
-@
-
-<<>>=
+<<eval=FALSE>>=
## for code compiled on the fly using cxxfunction() into 'fx_vec', we use
mod_vec <- Module( "mod_vec", getDynLib(fx_vec), mustStart = TRUE )
vec <- mod_vec$vec
@@ -1137,8 +897,8 @@
@
The simplest way to load all functions and classes from a module directly
-into a package namespace is to use the \Sexpr{link("loadRcppModules" )} function
-within the \Sexpr{link(".onLoad" )} body.
+into a package namespace is to use the \code{loadRcppModules} function
+within the \code{.onLoad} body.
<<eval=FALSE>>=
.onLoad <- function(libname, pkgname) {
@@ -1157,7 +917,7 @@
RcppModules: yada, stdVector, NumEx
\end{verbatim}
-The \Sexpr{link("loadRcppModules" )} has a single argument \texttt{direct}
+The \code{loadRcppModules} function has a single argument \texttt{direct}
with a default value of \texttt{TRUE}. With this default value, all content
from the module is exposed directly in the package namespace. If set to
\texttt{FALSE}, all content is exposed as components of the module.
@@ -1199,7 +959,7 @@
\subsection{Support for modules in skeleton generator}
-The \Sexpr{link("Rcpp.package.skeleton")} function has been improved to help
+The \code{Rcpp.package.skeleton} function has been improved to help
\pkg{Rcpp} modules. When the \texttt{module} argument is set to \texttt{TRUE},
the skeleton generator installs code that uses a simple module.
@@ -1213,8 +973,8 @@
\subsection{Module documentation}
-\pkg{Rcpp} defines a \Sexpr{link("prompt")} method for the
-\Sexpr{linkS4class("Module")} class, allowing generation of a skeleton of an Rd
+\pkg{Rcpp} defines a \code{prompt} method for the
+\code{Module} class, allowing generation of a skeleton of an Rd
file containing some information about the module.
<<eval=FALSE>>=
More information about the Rcpp-commits
mailing list