[Rcpp-commits] r1468 - pkg/Rcpp/inst/doc/Rcpp-extending

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Jun 7 15:22:18 CEST 2010


Author: romain
Date: 2010-06-07 15:22:18 +0200 (Mon, 07 Jun 2010)
New Revision: 1468

Modified:
   pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw
Log:
first step : how to extend wrap

Modified: pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw
===================================================================
--- pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw	2010-06-07 12:51:06 UTC (rev 1467)
+++ pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw	2010-06-07 13:22:18 UTC (rev 1468)
@@ -40,6 +40,37 @@
 linkS4class <- function( cl, package, text = cl, root = "http://finzi.psych.upenn.edu/R/library/" ){
 	link( sprintf("%s-class", cl), package, text, root )
 }
+# this will be integrated to package highlight later
+ex_highlight <- function( file, external.highlight = TRUE, verbatim = FALSE ){
+	if( verbatim ){
+		writeLines( "\\begin{verbatim}" )
+		writeLines( readLines( file ) )
+		writeLines( "\\end{verbatim}" )
+	} else {
+		tf <- tempfile()
+		if( external.highlight ){
+			cmd <- sprintf( 'highlight --input="%s" --output="%s" -L --pretty-symbols', file, tf )
+			tryCatch( {
+				system( cmd )
+				tex <- readLines( tf )
+				keep <- seq( which( tex == "\\noindent" ), which( tex == "\\normalfont" ) )
+				tex <- c(
+					"\\vspace{1em}\\noindent\\fbox{\\begin{minipage}{0.9\\textwidth}" ,
+					tex[ keep ],
+					"\\end{minipage}}\\vspace{1em}" )
+				writeLines( tex )
+			})
+		} else {
+			r = renderer_latex( minipage = TRUE, doc = FALSE )
+			tex <- highlight( file, renderer = r , output = NULL )
+			writeLines( tex )
+		}
+	}
+	invisible(NULL)
+}
+
+require( inline )
+require( Rcpp )
 @
 
 \begin{document}
@@ -73,14 +104,121 @@
 
 These converters are often used implicitely, as in the following code chunk:
 
-<<lang=cpp>>=
+<<echo=FALSE>>=
+code <- '
+// we get a list from R
+List input(input_) ;
 
+// pull std::vector<double> from R list
+// this is achieved through an implicit call to Rcpp::as
+std::vector<double> x = input["x"] ;
+
+// return an R list
+// this is achieved through implicit call to Rcpp::wrap
+return List::create( 
+	_["front"] = x.front(), 
+	_["back"]  = x.back()
+	) ;
+'
+writeLines( code, "code.cpp" )
 @
+<<echo=FALSE,results=tex>>=
+ex_highlight( "code.cpp" )
+@
 
+<<>>=
+fx <- cxxfunction( signature( input_ = "list"), 
+	paste( readLines( "code.cpp" ), collapse = "\n" ), 
+	plugin = "Rcpp"
+	)
+input <- list( x = seq(1, 10, by = 0.5) )
+fx( input )
+@
 
+\pkg{Rcpp} converters \texttt{Rcpp::as} and \texttt{Rcpp::wrap} have been 
+designed to be extensible to user defined types and third party types.
 
+\section[Extending Rcpp::wrap]{Extending \texttt{Rcpp::wrap} }
 
+The \pkg{Rcpp::wrap} converter is extensible in essentially two ways : intrusive 
+and non-intrusive. 
 
+\subsection{Intrusive extension}
+
+When extending \pkg{Rcpp} with your own data type, the recommended way to 
+let \texttt{Rcpp::wrap} know about them is to implement a conversion to 
+\texttt{SEXP}. The template meta programming dispatch is able to recognize that
+a type is convertible to a \texttt{SEXP} and \texttt{Rcpp::wrap} will use
+that conversion. 
+
+The caveat is that the type must be declared before the main header 
+file \texttt{Rcpp.h} is included. 
+
+<<echo=FALSE>>=
+code <- '
+#include <RcppCommon.h>
+
+class Foo{
+    public:
+        Foo() ;
+        operator SEXP() ;
+}
+
+#include <Rcpp.h>
+'
+writeLines( code, "code.cpp" )
+@
+
+<<echo=FALSE,results=tex>>=
+ex_highlight( "code.cpp" )
+@
+
+This is called \emph{intrusive} because the conversion to \texttt{SEXP}
+operator has to be declared within the class. 
+
+\subsection{Non intrusive extension}
+
+It is often desirable to offer automatic conversion to third-party types, over
+which the developer has no control and can therefore not include a conversion 
+to \texttt{SEXP} operator in the class definition. 
+
+To provide automatic conversion from \proglang{C++} to \proglang{R}, one must 
+declare a specialization of the \texttt{Rcpp::wrap} template between
+\texttt{RcppCommon.h} and \texttt{Rcpp.h} includes. 
+
+<<echo=FALSE>>=
+code <- '
+#include <RcppCommon.h>
+
+// third party library that declares class Bar
+#include <foobar.h>
+
+// declaring the specialization
+namespace Rcpp{
+    template <> SEXP wrap( const Bar& ) ;
+}
+
+// this must appear after the specialization, 
+// otherwise the specialization will not be seen by Rcpp types
+#include <Rcpp.h>
+'
+writeLines( code, "code.cpp" )
+@
+
+<<echo=FALSE,results=tex>>=
+ex_highlight( "code.cpp" )
+@
+
+It should be noted that only the declaration is required, the implementation
+can appear after the \texttt{Rcpp.h} file is included, and therefore take 
+full advantage of the \pkg{Rcpp} type system.
+
+
+<<echo=FALSE>>=
+unlink( "code.cpp" )
+@
+
+
 \bibliographystyle{abbrvnat}
 \bibliography{Rcpp-modules}
 



More information about the Rcpp-commits mailing list