[Rcpp-commits] r548 - pkg/src/Rcpp/internal

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Feb 1 19:06:39 CET 2010


Author: romain
Date: 2010-02-01 19:06:39 +0100 (Mon, 01 Feb 2010)
New Revision: 548

Modified:
   pkg/src/Rcpp/internal/wrap.h
Log:
documenting wrap implementations

Modified: pkg/src/Rcpp/internal/wrap.h
===================================================================
--- pkg/src/Rcpp/internal/wrap.h	2010-02-01 17:36:11 UTC (rev 547)
+++ pkg/src/Rcpp/internal/wrap.h	2010-02-01 18:06:39 UTC (rev 548)
@@ -84,6 +84,12 @@
 
 // {{{ range wrap 
 // {{{ unnamed range wrap
+/**
+ * Range based wrap implementation that deals with iterator over
+ * primitive types (int, double, etc ...)
+ * 
+ * This produces an unnamed vector of the appropriate type
+ */
 template <typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_primitive_tag){ 
 	size_t size = std::distance( first, last ) ;
@@ -94,6 +100,11 @@
 	return x ;
 } ;
 
+/**
+ * Range based wrap implementation that deals with iterators over bool
+ * 
+ * This produces an unnamed logical vector
+ */
 template <typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_bool_tag){ 
 	size_t size = std::distance( first, last ) ;
@@ -104,8 +115,12 @@
 } ;
 
 
-// this implementation is used when T is not a primitive type.
-// T needs to be wrappable though
+/** 
+ * range based wrap implementation that deals with iterators over 
+ * some type U. each U object is itself wrapped
+ * 
+ * This produces an unnamed generic vector (list)
+ */
 template <typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_generic_tag ){ 
 	size_t size = std::distance( first, last ) ;
@@ -120,6 +135,11 @@
 	return x ;
 } ;
 
+/**
+ * Range based wrap implementation for iterators over std::string
+ * 
+ * This produces an unnamed character vector
+ */
 template<typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_string_tag ){
 	size_t size = std::distance( first, last ) ;
@@ -136,6 +156,11 @@
 	return x ;
 }
 
+/**
+ * Dispatcher for all range based wrap implementations
+ * 
+ * This uses the Rcpp::traits::r_type_traits to perform further dispatch
+ */
 template<typename InputIterator, typename T>
 SEXP range_wrap_dispatch( InputIterator first, InputIterator last ){
 	return range_wrap_dispatch___impl<InputIterator,T>( first, last, typename ::Rcpp::traits::r_type_traits<T>::r_category() ) ;
@@ -143,8 +168,12 @@
 // }}}
 
 // {{{ named range wrap
-// we get into these when iterating over a pair<const string,T> 
-// which is what e.g. map<string,T> produces
+/** 
+ * range based wrap implementation that deals with iterators over
+ * pair<const string,T> where T is a primitive type : int, double ...
+ * 
+ * This produces a named R vector of the appropriate type
+ */
 template <typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_pairstring_primitive_tag){ 
 	size_t size = std::distance( first, last ) ;
@@ -164,6 +193,12 @@
 	return x ;
 } ;
 
+/**
+ * Range based wrap implementation that deals with iterators
+ * over pair<const string,bool>
+ *
+ * This produces a named character vector
+ */
 template <typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_pairstring_bool_tag){ 
 	size_t size = std::distance( first, last ) ;
@@ -183,8 +218,17 @@
 } ;
 
 
-// this implementation is used when T is not a primitive type.
-// T needs to be wrappable though
+/**
+ * Range based wrap implementation that deals with iterators over
+ * pair<const string, U> where U is wrappable. This is the kind of 
+ * iterators that are produced by map<string,U>
+ * 
+ * This produces a named generic vector (named list). The first 
+ * element of the list contains the result of a call to wrap on the 
+ * object of type U, etc ...
+ *
+ * The names are taken from the keys
+ */
 template <typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_pairstring_generic_tag ){ 
 	size_t size = std::distance( first, last ) ;
@@ -206,6 +250,16 @@
 	return x ;
 } ;
 
+/**
+ * Range based wrap for iterators over std::pair<const std::string, std::string>
+ *
+ * This is mainly used for wrapping map<string,string> and friends 
+ * which happens to produce iterators over pair<const string, string>
+ *
+ * This produces a character vector containing copies of the 
+ * string iterated over. The names of the vector is set to the keys
+ * of the pair
+ */
 template<typename InputIterator, typename T>
 SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_pairstring_string_tag ){
 	size_t size = std::distance( first, last ) ;
@@ -230,6 +284,10 @@
 // }}}
 
 // we use the iterator trait to make the dispatch
+/**
+ * range based wrap. This uses the std::iterator_traits class
+ * to perform further dispatch
+ */
 template <typename InputIterator>
 SEXP range_wrap(InputIterator first, InputIterator last){
 	return range_wrap_dispatch<InputIterator,typename std::iterator_traits<InputIterator>::value_type>( first, last ) ;
@@ -238,7 +296,11 @@
 
 // {{{ primitive wrap (wrapping a single primitive value)
 
-// for 'easy' primitive types: int, double, Rbyte, Rcomplex
+/**
+ * primitive wrap for 'easy' primitive types: int, double, Rbyte, Rcomplex
+ *
+ * This produces a vector of length 1 of the appropriate type
+ */
 template <typename T>
 SEXP primitive_wrap__impl( const T& object, ::Rcpp::traits::r_type_primitive_tag ){
 	const int RTYPE = r_sexptype<T>::rtype ;
@@ -248,7 +310,11 @@
 	return x;
 }
 
-// for bool
+/**
+ * primitive wrap for bool
+ *
+ * This produces a logical vector of length 1
+ */
 template <typename T>
 SEXP primitive_wrap__impl( const T& object, ::Rcpp::traits::r_type_bool_tag){
 	SEXP x = PROTECT( ::Rf_allocVector( LGLSXP, 1) );
@@ -257,7 +323,11 @@
 	return x;
 }
 
-// for std::string
+/**
+ * primitive wrap for types that can be converted implicitely to std::string
+ * 
+ * This produces a character vector of length 1 containing the std::string
+ */
 template <typename T>
 SEXP primitive_wrap__impl( const T& object, ::Rcpp::traits::r_type_string_tag){
 	SEXP x = PROTECT( ::Rf_allocVector( STRSXP, 1) ) ;
@@ -267,8 +337,12 @@
 	return x; 
 }
 
-// T is a primitive type : int, bool, double, std::string, etc ...
-// wrapping this in an R vector of the appropriate type
+/**
+ * called when T is a primitive type : int, bool, double, std::string, etc ...
+ * This uses the Rcpp::traits::r_type_traits on the type T to perform
+ * further dispatching and wrap the object into an vector of length 1
+ * of the appropriate SEXP type 
+ */
 template <typename T>
 SEXP primitive_wrap(const T& object){
 	return primitive_wrap__impl( object, typename ::Rcpp::traits::r_type_traits<T>::r_category() ) ;
@@ -276,12 +350,22 @@
 // }}}
 
 // {{{ unknown
+/**
+ * Called when the type T is known to be implicitely convertible to 
+ * SEXP. It uses the implicit conversion to SEXP to wrap the object
+ * into a SEXP
+ */
 template <typename T>
 SEXP wrap_dispatch_unknown( const T& object, true_type ){
 	// here we know (or assume) that T is convertible to SEXP
 	SEXP x = object ;
 	return x ;
 }
+
+/** 
+ * Called when no implicit conversion to SEXP is possible
+ * This generates compile time errors
+ */
 template <typename T>
 SEXP wrap_dispatch_unknown( const T& object, false_type){
 	// here we know that T is not convertible to SEXP
@@ -297,16 +381,32 @@
 // }}}
 
 // {{{ wrap dispatch
-// generic wrap for stl containers
+/** 
+ * generic wrap for stl containers. This implementation is used
+ * when the type T is an STL-like container, with a begin() method
+ * and an end() method
+ *
+ * further dispatch is performed internally by the range_wrap 
+ * template based on the type of object iterated over
+ */
 template <typename T> SEXP wrap_dispatch( const T& object, ::Rcpp::traits::wrap_type_stl_container_tag ){
 	return range_wrap( object.begin(), object.end() ) ;
 }
-// wrapping a primitive type : int, double, std::string
+
+/**
+ * wrapping a __single__ primitive type : int, double, std::string, size_t, 
+ * Rbyte, Rcomplex
+ */
 template <typename T> SEXP wrap_dispatch( const T& object, ::Rcpp::traits::wrap_type_primitive_tag ){
 	return primitive_wrap( object ) ;
 }
-// when we don't know how to deal with it, we try implicit conversion
-// if the type T is convertible to SEXP
+
+/** 
+ * This is called by wrap when the wrap_type_traits is wrap_type_unknown_tag
+ * This tries to identify is an implicit conversion to SEXP is possible
+ * ( the type T defines operator SEXP() ) and uses it, otherwise generates
+ * a compile error
+ */
 template <typename T> SEXP wrap_dispatch( const T& object, ::Rcpp::traits::wrap_type_unknown_tag ){
 	return wrap_dispatch_unknown( object, typename is_convertible<T,SEXP>::type() ) ;
 }
@@ -314,6 +414,17 @@
 
 } // internal
 
+/**
+ * wraps an object of type T in a SEXP
+ *
+ * This method depends on the Rcpp::traits::wrap_type_traits trait 
+ * class to dispatch to the appropriate internal implementation 
+ * method
+ * 
+ * If your type has a begin and end method returning stl-like iterator
+ * you should specialize the wrap_type_traits template so that it 
+ * defines wrap_category to be ::Rcpp::traits::wrap_type_stl_container_tag
+ */
 template <typename T> SEXP wrap(const T& object){
 	return internal::wrap_dispatch( object, typename ::Rcpp::traits::wrap_type_traits<T>::wrap_category() ) ;
 }



More information about the Rcpp-commits mailing list