[Rcpp-commits] r740 - in pkg/Rcpp: inst src/Rcpp/internal src/Rcpp/traits

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Fri Feb 19 12:37:05 CET 2010


Author: romain
Date: 2010-02-19 12:37:05 +0100 (Fri, 19 Feb 2010)
New Revision: 740

Modified:
   pkg/Rcpp/inst/ChangeLog
   pkg/Rcpp/src/Rcpp/internal/wrap.h
   pkg/Rcpp/src/Rcpp/traits/has_iterator.h
   pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h
Log:
manage new wrap capability differently so that we can use it for both RcppArmadillo and RProtoBuf

Modified: pkg/Rcpp/inst/ChangeLog
===================================================================
--- pkg/Rcpp/inst/ChangeLog	2010-02-19 08:57:37 UTC (rev 739)
+++ pkg/Rcpp/inst/ChangeLog	2010-02-19 11:37:05 UTC (rev 740)
@@ -1,12 +1,13 @@
 2010-02-19  Romain Francois <romain at r-enthusiasts.com>
 
-	* src/Rcpp/traits/wrap_type_traits.h : a new category of wrappable
-	objects : wrap_type_indexable_tag was introduced to facilitate
-	the implementation of wrap< arma::Field<T> > in RcppArmadillo
-	This category is usable when the type has an operator[](int)
-	To use it, the client must specialize the templates :
-	Rcpp::traits::get_size and Rcpp::traits::get_value_type
-	An example is given in RcppArmadillo.
+	* src/Rcpp/traits/wrap_type_traits.h : The Importer concept 
+	has been introduced to support wrap() of more types. If a 
+	class has a typedef "r_import_type" then the following interface
+	is assumed and used. The corresponding class must have methods 
+	int size() and r_import_type get(int). As usual further dispatch
+	is performed based on r_import_type (primitive, etc ...). 
+	RcppArmadillo has an example of this for wrapping arma::field<T>
+	objects using the FieldImporter<T> class.
 
 2010-02-18  Romain Francois <romain at r-enthusiasts.com>
 

Modified: pkg/Rcpp/src/Rcpp/internal/wrap.h
===================================================================
--- pkg/Rcpp/src/Rcpp/internal/wrap.h	2010-02-19 08:57:37 UTC (rev 739)
+++ pkg/Rcpp/src/Rcpp/internal/wrap.h	2010-02-19 11:37:05 UTC (rev 740)
@@ -417,14 +417,14 @@
 }
 
 template <typename T, typename elem_type>
-SEXP indexing_wrap_dispatch___impl__prim( const T& object, ::Rcpp::traits::false_type ){
-	int size = ::Rcpp::traits::get_size<T>().size() ;
+SEXP wrap_dispatch_importer__impl__prim( const T& object, ::Rcpp::traits::false_type ){
+	int size = object.size() ;
 	const int RTYPE = ::Rcpp::traits::r_sexptype_traits<elem_type>::rtype ;
 	SEXP x = PROTECT( Rf_allocVector( RTYPE, size ) );
-	typedef typename ::Rcpp::traits::storage_type<RTYPE> CTYPE ;
-	CTYPE* start = r_vector_start< RTYPE, typename ::Rcpp::traits::storage_type<RTYPE>::type >(x) ;
+	typedef typename ::Rcpp::traits::storage_type<RTYPE>::type CTYPE ;
+	CTYPE* start = r_vector_start<RTYPE,CTYPE>(x) ;
 	for( int i=0; i<size; i++){
-		start[i] = object[i] ;
+		start[i] = object.get(i) ;
 	}
 	UNPROTECT(1) ;
 	return x ;
@@ -432,28 +432,28 @@
 }
 
 template <typename T, typename elem_type>
-SEXP indexing_wrap_dispatch___impl__prim( const T& object, ::Rcpp::traits::true_type ){
-	int size = ::Rcpp::traits::get_size<T>().size() ;
+SEXP wrap_dispatch_importer__impl__prim( const T& object, ::Rcpp::traits::true_type ){
+	int size = object.size() ;
 	const int RTYPE = ::Rcpp::traits::r_sexptype_traits<elem_type>::rtype ;
 	SEXP x = PROTECT( Rf_allocVector( RTYPE, size ) );
-	typedef typename ::Rcpp::traits::storage_type<RTYPE> CTYPE ;
-	CTYPE* start = r_vector_start< RTYPE, typename ::Rcpp::traits::storage_type<RTYPE>::type >(x) ;
+	typedef typename ::Rcpp::traits::storage_type<RTYPE>::type CTYPE ;
+	CTYPE* start = r_vector_start<RTYPE,CTYPE>(x) ;
 	for( int i=0; i<size; i++){
-		start[i] = caster<elem_type,CTYPE>( object[i] );
+		start[i] = caster<elem_type,CTYPE>( object.get(i) );
 	}
 	UNPROTECT(1) ;
 	return x ;
 }
 
 template <typename T, typename elem_type>
-SEXP indexing_wrap_dispatch___impl( const T& object, ::Rcpp::traits::wrap_type_primitive_tag ){
-	return indexing_wrap_dispatch___impl__prim<T,elem_type>( object, 
+SEXP wrap_dispatch_importer__impl( const T& object, ::Rcpp::traits::wrap_type_primitive_tag ){
+	return wrap_dispatch_importer__impl__prim<T,elem_type>( object, 
 		typename ::Rcpp::traits::r_sexptype_needscast<elem_type>() ) ;
 }
 
 template <typename T, typename elem_type>
-SEXP wrap_dispatch_indexable( const T& object ){
-	return indexing_wrap_dispatch___impl<T,elem_type>( object, 
+SEXP wrap_dispatch_importer( const T& object ){
+	return wrap_dispatch_importer__impl<T,elem_type>( object, 
 		typename ::Rcpp::traits::r_type_traits<elem_type>::r_category() 
 		 ) ;
 }
@@ -478,24 +478,31 @@
 	return primitive_wrap( object ) ;
 }
 
-/** 
- * 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
+/**
+ * called when T is wrap_type_unknown_tag and is not an Importer class
+ * The next step is to try implicit conversion to SEXP
  */
-template <typename T> SEXP wrap_dispatch( const T& object, ::Rcpp::traits::wrap_type_unknown_tag ){
+template <typename T> SEXP wrap_dispatch_unknown_importable( const T& object, ::Rcpp::traits::false_type){
 	return wrap_dispatch_unknown( object, typename is_convertible<T,SEXP>::type() ) ;
 }
-// }}}
 
 /**
- * Used when the type is identifies as indexable, i.e. falls into the 
- * wrap_type_indexable_tag category
+ * called when T is an Importer
  */
-template <typename T> SEXP wrap_dispatch( const T& object, ::Rcpp::traits::wrap_type_indexable_tag ){
-	return wrap_dispatch_indexable< T, typename ::Rcpp::traits::get_value_type<T>::value_type >( object ) ;
+template <typename T> SEXP wrap_dispatch_unknown_importable( const T& object, ::Rcpp::traits::true_type){
+	return wrap_dispatch_importer<T,typename T::r_import_type>( object ) ;
 }
+ 
+ 
+/** 
+ * This is called by wrap when the wrap_type_traits is wrap_type_unknown_tag
+ * 
+ * This tries to identify if the object conforms to the Importer class
+ */
+template <typename T> SEXP wrap_dispatch( const T& object, ::Rcpp::traits::wrap_type_unknown_tag ){
+	return wrap_dispatch_unknown_importable( object, typename ::Rcpp::traits::is_importer<T>::type() ) ;
+}
+	// }}}
 
 } // internal
 

Modified: pkg/Rcpp/src/Rcpp/traits/has_iterator.h
===================================================================
--- pkg/Rcpp/src/Rcpp/traits/has_iterator.h	2010-02-19 08:57:37 UTC (rev 739)
+++ pkg/Rcpp/src/Rcpp/traits/has_iterator.h	2010-02-19 11:37:05 UTC (rev 740)
@@ -50,6 +50,20 @@
       static const bool value = sizeof(__test<T>(0)) == 1;
     };
 
+  template<typename T>
+  class _is_importer_helper : __sfinae_types {
+      template<typename U> struct _Wrap_type { };
+
+      template<typename U>
+        static __one __test(_Wrap_type<typename U::r_import_type>*);
+
+      template<typename U>
+        static __two __test(...);
+
+    public:
+      static const bool value = sizeof(__test<T>(0)) == 1;
+    };
+  
   /** 
    * uses the SFINAE idiom to check if a class has an 
    * nested iterator typedef. For example : 
@@ -60,6 +74,17 @@
   template<typename T> struct has_iterator : 
   	integral_constant<bool,_has_iterator_helper<T>::value> { };
 
+  /**
+   * uses SFINAE to identify if a type is importable, i.e. if it conforms
+   * to the Rcpp::traits::Importer interface.
+   *
+   * The test is based on the presence of a typedef r_import_type in the 
+   * class
+   */
+  template<typename T> struct is_importer : 
+    integral_constant<bool,_is_importer_helper<T>::value> { };
+	
+  	
 } // traits
 } // Rcpp
 

Modified: pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h
===================================================================
--- pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h	2010-02-19 08:57:37 UTC (rev 739)
+++ pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h	2010-02-19 11:37:05 UTC (rev 740)
@@ -37,21 +37,6 @@
 struct wrap_type_unknown_tag{};          // unknown, not sure what to do with this type
 
 /**
- * used when the type has an indexing operator operator[]( int )
- * 
- * No attempt is made to guess if the type falls into this category, 
- * so the client has to specifically declare it.
- *
- * In addition : 
- * - the get_size template function should also be 
- * specialized, unless the type has a size method that returns the 
- * number of elements
- *
- * - the get_value type struct has to be defined
- */
-struct wrap_type_indexable_tag{} ;
-
-/**
  * Type trait that helps the dispatch of wrap to the proper method
  *
  * This builds a struct that contains a typedef called wrap_category
@@ -75,30 +60,6 @@
 template <> struct wrap_type_traits<char> { typedef wrap_type_primitive_tag wrap_category; } ;
 template <> struct wrap_type_traits<float> { typedef wrap_type_primitive_tag wrap_category; } ;
 
-/**
- * Returns the number of elements in the object. 
- *
- * This is used by the wrap_type_indexable_tag category of wrappable objects.
- */
-template <typename T> class get_size {
-public:
-	get_size(const T& object) : size_( object.size() ){} ;
-	int size(){ return size_ ; }
-private:
-	int size_ ;
-} ;
-
-/**
- * Indicates the value_type of an indexable object.
- * 
- * This is used by wrap when dealing with objects that fall in the 
- * wrap_type_indexable_tag category
- */
-template <typename T> struct get_value_type{
-	typedef int value_type ;
-} ;
-
-
 } // namespace traits
 } // namespace Rcpp
 #endif



More information about the Rcpp-commits mailing list