[Rcpp-commits] r756 - in pkg/Rcpp: inst src src/Rcpp
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sun Feb 21 19:30:03 CET 2010
Author: romain
Date: 2010-02-21 19:30:03 +0100 (Sun, 21 Feb 2010)
New Revision: 756
Modified:
pkg/Rcpp/inst/ChangeLog
pkg/Rcpp/src/Rcpp/as.h
pkg/Rcpp/src/as.cpp
Log:
more generic as impl for primitive types
Modified: pkg/Rcpp/inst/ChangeLog
===================================================================
--- pkg/Rcpp/inst/ChangeLog 2010-02-21 18:16:26 UTC (rev 755)
+++ pkg/Rcpp/inst/ChangeLog 2010-02-21 18:30:03 UTC (rev 756)
@@ -1,3 +1,7 @@
+2010-02-21 Romain Francois <romain at r-enthusiasts.com>
+
+ * src/Rcpp/as.h: more generic as implementation for primitive types
+
2010-02-19 Romain Francois <romain at r-enthusiasts.com>
* src/Rcpp/as.h: as now delegates to a template class
Modified: pkg/Rcpp/src/Rcpp/as.h
===================================================================
--- pkg/Rcpp/src/Rcpp/as.h 2010-02-21 18:16:26 UTC (rev 755)
+++ pkg/Rcpp/src/Rcpp/as.h 2010-02-21 18:30:03 UTC (rev 756)
@@ -24,6 +24,36 @@
namespace Rcpp{
+namespace internal{
+
+ template <typename T> T as( SEXP x, ::Rcpp::traits::r_type_primitive_tag ){
+ if( ::Rf_length(x) != 1 ) throw std::range_error( "expecting a single value" ) ;
+ const int RTYPE = ::Rcpp::traits::r_sexptype_traits<T>::rtype ;
+ SEXP y = r_cast<RTYPE>(x) ;
+ typedef typename ::Rcpp::traits::storage_type<RTYPE>::type STORAGE;
+ T res = caster<STORAGE,T>( *r_vector_start<RTYPE,STORAGE>( y ) ) ;
+ UNPROTECT(1) ;
+ return res ;
+ }
+
+ template <typename T> T as(SEXP x, ::Rcpp::traits::r_type_string_tag ){
+ if( ! ::Rf_isString(x) ){
+ throw std::range_error( "expecting a string" ) ;
+ }
+ if (Rf_length(x) != 1) {
+ throw std::range_error( "expecting a single value");
+ }
+ return T( CHAR( STRING_ELT(x,0 ) ) ) ;
+ }
+
+ template <typename T> T as(SEXP x, ::Rcpp::traits::r_type_generic_tag ){
+ traits::Exporter<T> exporter(x);
+ return exporter.get() ;
+ }
+
+}
+
+
/**
* Generic converted from SEXP to the typename. T can be any type that
* has a constructor taking a SEXP, which is the case for all our
@@ -40,55 +70,12 @@
* Foo y = x["bla"] ; // if as<Foo> makes sense then this works !!
*/
template <typename T> T as( SEXP m_sexp) {
- traits::Exporter<T> exporter(m_sexp);
- return exporter.get() ;
+ return internal::as<T>( m_sexp, typename traits::r_type_traits<T>::r_category() ) ;
}
template<> SEXP as(SEXP m_sexp) ;
/**
- * Converts the R object to a bool.
- *
- * The R object must be either a logical, integer, raw or numeric vector
- * and must have only one element. An exception is thrown otherwise
- *
- * bool can not handle missing values, so NA are converted to false
- */
-template<> bool as<bool>(SEXP m_sexp) ;
-
-/**
- * Converts the R object to a double
- *
- * The R object must be either a logical, integer, raw or numeric vector
- * and must have only one element. An exception is thrown otherwise
- */
-template<> double as<double>(SEXP m_sexp) ;
-
-/**
- * Converts the R object to an int
- *
- * The R object must be either a logical, integer, raw or numeric vector
- * and must have only one element. An exception is thrown otherwise
- */
-template<> int as<int>(SEXP m_sexp) ;
-
-/**
- * Converts the R object to a Rbyte
- *
- * The R object must be either a logical, integer, raw or numeric vector
- * and must have only one element. An exception is thrown otherwise
- */
-template<> Rbyte as<Rbyte>(SEXP m_sexp) ;
-
-/**
- * Converts the R object to a std::string
- *
- * The R object must be a character vector of length 1.
- * An exception is thrown otherwise
- */
-template<> std::string as<std::string>(SEXP m_sexp) ;
-
-/**
* Converts the R object to a std::vector<std::string>
*
* The R object must be a character vector
Modified: pkg/Rcpp/src/as.cpp
===================================================================
--- pkg/Rcpp/src/as.cpp 2010-02-21 18:16:26 UTC (rev 755)
+++ pkg/Rcpp/src/as.cpp 2010-02-21 18:30:03 UTC (rev 756)
@@ -27,92 +27,6 @@
return m_sexp ;
}
-template<> double as<double>(SEXP m_sexp) {
- if (Rf_length(m_sexp) != 1) {
- throw std::range_error("as<double> expects single value");
- }
- switch( TYPEOF(m_sexp) ){
- case LGLSXP:
- return internal::r_coerce<LGLSXP,REALSXP>( LOGICAL(m_sexp)[0] ) ;
- case REALSXP:
- return REAL(m_sexp)[0] ;
- case INTSXP:
- return internal::r_coerce<INTSXP,REALSXP>( INTEGER(m_sexp)[0] );
- case RAWSXP:
- return internal::r_coerce<RAWSXP,REALSXP>( RAW(m_sexp)[0] );
- default:
- throw std::range_error("as<double> invalid type");
- }
- return 0.0 ; // never reached
-}
-
-template<> int as<int>(SEXP m_sexp) {
- if (Rf_length(m_sexp) != 1) {
- throw std::range_error("as<int> expects single value");
- }
- switch( TYPEOF(m_sexp)){
- case LGLSXP:
- return internal::r_coerce<LGLSXP,INTSXP>( LOGICAL(m_sexp)[0] ) ;
- case REALSXP:
- return internal::r_coerce<REALSXP,INTSXP>( REAL(m_sexp)[0] ); // some of this might be lost
- case INTSXP:
- return INTEGER(m_sexp)[0];
- case RAWSXP:
- return internal::r_coerce<RAWSXP,INTSXP>( RAW(m_sexp)[0] );
- default:
- throw std::range_error("as<int>");
- }
- return 0; // never reached
-}
-
-template<> Rbyte as<Rbyte>(SEXP m_sexp) {
- if (Rf_length(m_sexp) != 1) {
- throw std::range_error("as<Rbyte> expects single value");
- }
- switch( TYPEOF(m_sexp) ){
- case LGLSXP:
- return internal::r_coerce<LGLSXP,RAWSXP>( LOGICAL(m_sexp)[0] ) ;
- case REALSXP:
- return internal::r_coerce<REALSXP,RAWSXP>( REAL(m_sexp)[0] );
- case INTSXP:
- return internal::r_coerce<INTSXP,RAWSXP>( INTEGER(m_sexp)[0] );
- case RAWSXP:
- return RAW(m_sexp)[0] ;
- default:
- throw std::range_error("as<Rbyte> expects raw, double or int");
- }
- return (Rbyte)0; // never reached
-}
-
-template<> bool as<bool>(SEXP m_sexp) {
- if (Rf_length(m_sexp) != 1) {
- throw std::range_error("as<bool> expects single value");
- }
- switch( TYPEOF(m_sexp) ){
- case LGLSXP:
- return LOGICAL(m_sexp)[0] ? true : false ;
- case REALSXP:
- return double_to_bool( REAL(m_sexp)[0] ) ;
- case INTSXP:
- return int_to_bool( INTEGER(m_sexp)[0] ) ;
- case RAWSXP:
- return Rbyte_to_bool( RAW(m_sexp)[0] );
- default:
- throw std::range_error("as<bool> expects raw, double or int");
- }
- return false; // never reached
-}
-
-template<> std::string as<std::string>(SEXP m_sexp) {
- if (Rf_length(m_sexp) != 1) {
- throw std::range_error("as<std::string> expects single value");
- }
- if (!Rf_isString(m_sexp)) {
- throw std::range_error("as<std::string> expects string");
- }
- return std::string(CHAR(STRING_ELT(m_sexp,0)));
-}
-
template<> std::vector<std::string> as< std::vector<std::string> >(SEXP m_sexp){
R_len_t n = Rf_length(m_sexp);
std::vector<std::string> v(n);
More information about the Rcpp-commits
mailing list