[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