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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Jun 7 15:45:44 CEST 2010


Author: romain
Date: 2010-06-07 15:45:44 +0200 (Mon, 07 Jun 2010)
New Revision: 1469

Modified:
   pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw
Log:
end of first pass for Rcpp-extending vignette, covering Rcpp::as and Rcpp::wrap

Modified: pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw
===================================================================
--- pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw	2010-06-07 13:22:18 UTC (rev 1468)
+++ pkg/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw	2010-06-07 13:45:44 UTC (rev 1469)
@@ -154,25 +154,20 @@
 The caveat is that the type must be declared before the main header 
 file \texttt{Rcpp.h} is included. 
 
-<<echo=FALSE>>=
-code <- '
+<<lang=cpp>>=
 #include <RcppCommon.h>
 
 class Foo{
     public:
         Foo() ;
+        
+        // this operator enables implicit Rcpp::wrap
         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. 
 
@@ -186,8 +181,7 @@
 declare a specialization of the \texttt{Rcpp::wrap} template between
 \texttt{RcppCommon.h} and \texttt{Rcpp.h} includes. 
 
-<<echo=FALSE>>=
-code <- '
+<<lang=cpp>>=
 #include <RcppCommon.h>
 
 // third party library that declares class Bar
@@ -197,23 +191,142 @@
 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.
 
+\subsection{Templates and partial specialization}
 
+It is perfectly valid to declare a partial specialization for the 
+\texttt{Rcpp::wrap} template. The compiler will identify the appropriate 
+overload: 
+
+<<lang=cpp>>=
+#include <RcppCommon.h>
+
+// third party library that declares template class Bling<T>
+#include <foobar.h>
+
+// declaring the partial specialization
+namespace Rcpp{ namespace traits {
+    
+    template <typename T> SEXP wrap( const Bling<T>& ) ;
+
+} }
+                                
+// this must appear after the specialization, 
+// otherwise the specialization will not be seen by Rcpp types
+#include <Rcpp.h>
+
+@
+
+
+\section[Extending Rcpp::as]{Extending \texttt{Rcpp::as}}
+
+Conversion from \proglang{R} to \proglang{C++} is also possible 
+in both intrusive and non-intrusive ways. 
+
+\subsection{Intrusive extension}
+
+As part of its template meta programming dispatch logic, \pkg{Rcpp::as}
+will attempt to use the constructor of the target class taking a \texttt{SEXP}. 
+
+<<lang=cpp>>=
+#include <RcppCommon.h>
+
+#include <RcppCommon.h>
+
+class Foo{
+    public:
+        Foo() ;
+        
+        // this constructor enables implicit Rcpp::as
+        Foo(SEXP) ;
+}
+
+#include <Rcpp.h>
+
+
+// this must appear after the specialization, 
+// otherwise the specialization will not be seen by Rcpp types
+#include <Rcpp.h>
+@
+
+\subsection{Non intrusive extension}
+
+It is also possible to fully specialize \texttt{Rcpp::as} to enable 
+non intrusive implicit conversion capabilities.
+
+<<lang=cpp>>=
+#include <RcppCommon.h>
+
+// third party library that declares class Bar
+#include <foobar.h>
+
+// declaring the specialization
+namespace Rcpp{
+    template <> Bar as( SEXP ) throw(not_compatible) ;
+}
+                                
+// this must appear after the specialization, 
+// otherwise the specialization will not be seen by Rcpp types
+#include <Rcpp.h>
+@
+
+\subsection{Templates and partial specialization}
+
+The signature of \texttt{Rcpp::as} does not allow partial specialization. 
+
+When exposing a templated class to \texttt{Rcpp::as}, the programmer must 
+specialize the \pkg{Rcpp::traits::Exporter} template class. The TMP dispatch 
+will recognize that a specialization of \texttt{Exporter} is available
+and delegate the conversion to this class. \pkg{Rcpp} defines 
+the \texttt{Rcpp::traits::Exporter} template class as follows :
+
+<<lang=cpp>>=
+namespace Rcpp{ namespace traits{
+
+    template <typename T> class Exporter{
+    public:
+        Exporter( SEXP x ) : t(x){}
+        inline T get(){ return t ; }
+    
+    private:
+        T t ;
+    } ;
+
+}Ê}
+@
+
+This is the reason why the default behavior of \texttt{Rcpp::as} is to 
+invoke the constructor of the type \texttt{T} taking a \texttt{SEXP}.
+
+Since partial specialization of class templates is allowed, we can expose
+a set of classes as follows:
+
+<<lang=cpp>>=
+#include <RcppCommon.h>
+
+// third party library that declares template class Bling<T>
+#include <foobar.h>
+
+// declaring the partial specialization
+namespace Rcpp{ namespace traits {
+    template <typename T> class Exporter< Bling<T> >;
+} }
+                                
+// this must appear after the specialization, 
+// otherwise the specialization will not be seen by Rcpp types
+#include <Rcpp.h>
+
+@
+
 <<echo=FALSE>>=
 unlink( "code.cpp" )
 @



More information about the Rcpp-commits mailing list