[Rcpp-commits] r739 - 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 09:57:37 CET 2010


Author: romain
Date: 2010-02-19 09:57:37 +0100 (Fri, 19 Feb 2010)
New Revision: 739

Modified:
   pkg/Rcpp/DESCRIPTION
   pkg/Rcpp/inst/ChangeLog
   pkg/Rcpp/src/Rcpp/internal/wrap.h
   pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h
Log:
new category of wrappable objects, to support arma::field<T> in RcppArmadillo

Modified: pkg/Rcpp/DESCRIPTION
===================================================================
--- pkg/Rcpp/DESCRIPTION	2010-02-19 04:18:19 UTC (rev 738)
+++ pkg/Rcpp/DESCRIPTION	2010-02-19 08:57:37 UTC (rev 739)
@@ -1,6 +1,6 @@
 Package: Rcpp
 Title: Rcpp R/C++ interface package
-Version: 0.7.7.6
+Version: 0.7.7.7
 Date: $Date$
 Author: Dirk Eddelbuettel and Romain Francois, with contributions 
  by Simon Urbanek and David Reiss; based on code written during 

Modified: pkg/Rcpp/inst/ChangeLog
===================================================================
--- pkg/Rcpp/inst/ChangeLog	2010-02-19 04:18:19 UTC (rev 738)
+++ pkg/Rcpp/inst/ChangeLog	2010-02-19 08:57:37 UTC (rev 739)
@@ -1,3 +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.
+
 2010-02-18  Romain Francois <romain at r-enthusiasts.com>
 
 	* src/Rcpp/Language.h: added fixed_call to support STL algorithms

Modified: pkg/Rcpp/src/Rcpp/internal/wrap.h
===================================================================
--- pkg/Rcpp/src/Rcpp/internal/wrap.h	2010-02-19 04:18:19 UTC (rev 738)
+++ pkg/Rcpp/src/Rcpp/internal/wrap.h	2010-02-19 08:57:37 UTC (rev 739)
@@ -416,6 +416,48 @@
 	return range_wrap( object.begin(), object.end() ) ;
 }
 
+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() ;
+	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) ;
+	for( int i=0; i<size; i++){
+		start[i] = object[i] ;
+	}
+	UNPROTECT(1) ;
+	return x ;
+
+}
+
+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() ;
+	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) ;
+	for( int i=0; i<size; i++){
+		start[i] = caster<elem_type,CTYPE>( object[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, 
+		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, 
+		typename ::Rcpp::traits::r_type_traits<elem_type>::r_category() 
+		 ) ;
+}
+
 /** 
  * Called when no implicit conversion to SEXP is possible and this is 
  * not tagged as a primitive type, checks whether the type is 
@@ -447,6 +489,14 @@
 }
 // }}}
 
+/**
+ * Used when the type is identifies as indexable, i.e. falls into the 
+ * wrap_type_indexable_tag category
+ */
+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 ) ;
+}
+
 } // internal
 
 /**

Modified: pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h
===================================================================
--- pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h	2010-02-19 04:18:19 UTC (rev 738)
+++ pkg/Rcpp/src/Rcpp/traits/wrap_type_traits.h	2010-02-19 08:57:37 UTC (rev 739)
@@ -37,6 +37,21 @@
 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
@@ -60,6 +75,30 @@
 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