[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