[Rcpp-commits] r4237 - in pkg/Rcpp: . inst/include/Rcpp inst/include/Rcpp/internal inst/include/Rcpp/traits

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Feb 4 15:43:57 CET 2013


Author: romain
Date: 2013-02-04 15:43:57 +0100 (Mon, 04 Feb 2013)
New Revision: 4237

Added:
   pkg/Rcpp/inst/include/Rcpp/traits/char_type.h
Modified:
   pkg/Rcpp/ChangeLog
   pkg/Rcpp/inst/include/Rcpp/as.h
   pkg/Rcpp/inst/include/Rcpp/internal/export.h
   pkg/Rcpp/inst/include/Rcpp/internal/wrap.h
   pkg/Rcpp/inst/include/Rcpp/traits/r_type_traits.h
   pkg/Rcpp/inst/include/Rcpp/traits/traits.h
Log:
rework the wstring support to avoid having extra tag traits, the support is now handled at a lower level

Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog	2013-02-04 11:36:27 UTC (rev 4236)
+++ pkg/Rcpp/ChangeLog	2013-02-04 14:43:57 UTC (rev 4237)
@@ -1,9 +1,14 @@
 2013-02-04 Romain Francois <romain at r-enthusiasts.com>
 
-        * include/Rcpp/traits/r_type_traits.h : added the r_type_pairstring_wstring_tag tag
-        that is used to detect iterators over pair<const string,wstring>
+        * include/Rcpp/traits/r_type_traits.h : make the r_type_pairstring_string_tag tag
+        more general, handling wstring as well as string
         * include/Rcpp/internal/wrap.h : using make_charsexp, a more generic version
         of charsexp_from_wstring.
+        * include/Rcpp/as.h : more support fot wstring
+        * include/Rcpp/internal/wrap.h : rework the support of wstring
+        * include/Rcpp/internal/export.h : added as_string_elt to rework the support
+        of wstring 
+        * include/Rcpp/traits/char_type.h : new trait to help the wstring support 
         
 2013-02-03 Romain Francois <romain at r-enthusiasts.com>
 

Modified: pkg/Rcpp/inst/include/Rcpp/as.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/as.h	2013-02-04 11:36:27 UTC (rev 4236)
+++ pkg/Rcpp/inst/include/Rcpp/as.h	2013-02-04 14:43:57 UTC (rev 4237)
@@ -43,24 +43,28 @@
             return primitive_as<T>(x) ;
         }
         
-        template <typename T> T as(SEXP x, ::Rcpp::traits::r_type_string_tag ) {
+        inline const char* check_single_string( SEXP x){
             if( ! ::Rf_isString(x) )
                 throw ::Rcpp::not_compatible( "expecting a string" ) ;
             if (Rf_length(x) != 1)
                 throw ::Rcpp::not_compatible( "expecting a single value");
-            return T( CHAR( STRING_ELT( ::Rcpp::r_cast<STRSXP>(x) ,0 ) ) ) ;
+            return CHAR( STRING_ELT( ::Rcpp::r_cast<STRSXP>(x) ,0 ) ) ;
         }
         
-        template <typename T> T as(SEXP x, ::Rcpp::traits::r_type_wstring_tag ) {
-            if( ! ::Rf_isString(x) )
-                throw ::Rcpp::not_compatible( "expecting a string" ) ;
-            if (Rf_length(x) != 1)
-                throw ::Rcpp::not_compatible( "expecting a single value");
-            const char* y = CHAR( STRING_ELT( ::Rcpp::r_cast<STRSXP>(x) ,0 ) ) ;
-            // TODO: deal about encoding
+        
+        template <typename T> T as_string( SEXP x, Rcpp::traits::true_type){
+            const char* y = check_single_string(x) ;
             return std::wstring( y, y+strlen(y)) ;
         }
         
+        template <typename T> T as_string( SEXP x, Rcpp::traits::false_type){
+            return check_single_string(x) ;
+        }
+        
+        template <typename T> T as(SEXP x, ::Rcpp::traits::r_type_string_tag ) {
+            return as_string<T>( x, typename Rcpp::traits::is_wide_string<T>::type() );
+        }
+        
         template <typename T> T as(SEXP x, ::Rcpp::traits::r_type_RcppString_tag ) {
             if( ! ::Rf_isString(x) ){
                 throw ::Rcpp::not_compatible( "expecting a string" ) ;

Modified: pkg/Rcpp/inst/include/Rcpp/internal/export.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/internal/export.h	2013-02-04 11:36:27 UTC (rev 4236)
+++ pkg/Rcpp/inst/include/Rcpp/internal/export.h	2013-02-04 14:43:57 UTC (rev 4237)
@@ -27,6 +27,24 @@
 namespace Rcpp{
     namespace internal{
 
+    	
+		template <typename T>
+		std::wstring as_string_elt__impl( SEXP x, R_len_t i, Rcpp::traits::true_type ){
+			const char* y = char_get_string_elt( x, i ) ;
+			return std::wstring(y, y+strlen(y) ) ;
+		}
+		
+		template <typename T>
+		std::string as_string_elt__impl( SEXP x, R_len_t i, Rcpp::traits::false_type ){
+			return char_get_string_elt( x, i ) ;
+		}
+    	
+		template <typename T>
+		const std::basic_string< typename Rcpp::traits::char_type<T>::type > 
+		as_string_elt( SEXP x, R_len_t i ){
+			return as_string_elt__impl<T>( x, i, typename Rcpp::traits::is_wide_string<T>::type() ) ;
+		}
+    	
         /* iterating */
         
         template <typename InputIterator, typename value_type>
@@ -63,21 +81,10 @@
 			if( ! ::Rf_isString( x) ) throw ::Rcpp::not_compatible( "expecting a string vector" ) ;
 			R_len_t n = ::Rf_length(x) ;
 			for( R_len_t i=0; i<n; i++, ++first ){
-				*first = CHAR( STRING_ELT(x, i )) ;
+				*first = as_string_elt<typename std::iterator_traits<InputIterator>::value_type> ( x, i ) ;
 			}
 		}
         
-		// InputIterator is an iterator over std::wstring
-		template <typename InputIterator, typename value_type>
-		void export_range__dispatch( SEXP x, InputIterator first, ::Rcpp::traits::r_type_wstring_tag ) {
-			if( ! ::Rf_isString( x) ) throw ::Rcpp::not_compatible( "expecting a string vector" ) ;
-			R_len_t n = ::Rf_length(x) ;
-			for( R_len_t i=0; i<n; i++, ++first ){
-				const char* st = CHAR( STRING_ELT(x, i )) ;
-				*first = std::wstring( st, st + strlen(st) ) ;
-			}
-		}
-        
 		template <typename InputIterator>
 		void export_range( SEXP x, InputIterator first ) {
 			export_range__dispatch<InputIterator,typename std::iterator_traits<InputIterator>::value_type>( 
@@ -130,22 +137,11 @@
 			if( ! ::Rf_isString( x) ) throw Rcpp::not_compatible( "expecting a string vector" ) ;
 			R_len_t n = ::Rf_length(x) ;
 			for( R_len_t i=0; i<n; i++ ){
-				res[i] = CHAR( STRING_ELT(x, i )) ;
+				res[i] = as_string_elt< value_type >( x, i) ;
 			}
 		}
-        
-		// T is an array of wstring
+       
 		template <typename T, typename value_type>
-		void export_indexing__dispatch( SEXP x, T& res, ::Rcpp::traits::r_type_wstring_tag ) {
-			if( ! ::Rf_isString( x) ) throw Rcpp::not_compatible( "expecting a string vector" ) ;
-			R_len_t n = ::Rf_length(x) ;
-			for( R_len_t i=0; i<n; i++ ){
-				const char* st = CHAR( STRING_ELT(x, i )) ;
-				res[i] = std::wstring( st, st+strlen(st)) ;
-			}
-		}
-        
-		template <typename T, typename value_type>
 		void export_indexing( SEXP x, T& res ) {
 			export_indexing__dispatch<T,value_type>( 
 				x, 

Modified: pkg/Rcpp/inst/include/Rcpp/internal/wrap.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/internal/wrap.h	2013-02-04 11:36:27 UTC (rev 4236)
+++ pkg/Rcpp/inst/include/Rcpp/internal/wrap.h	2013-02-04 14:43:57 UTC (rev 4237)
@@ -204,25 +204,6 @@
 	return x ;
 }
 
-/**
- * Range based wrap implementation for iterators over std::wstring
- * 
- * This produces an unnamed character vector
- */
-template<typename InputIterator, typename T>
-inline SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_wstring_tag ){
-	size_t size = std::distance( first, last ) ;
-	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
-	size_t i = 0 ;
-	while( i < size ){
-		SET_STRING_ELT( x, i, make_charsexp(*first) ) ;
-		i++ ;
-		++first ;
-	}
-	UNPROTECT(1) ;
-	return x ;
-}
-
 // }}}
 
 // {{{ named range wrap
@@ -332,8 +313,9 @@
 	return x ;
 }
 
+
 /**
- * Range based wrap for iterators over std::pair<const std::string, std::string>
+ * Range based wrap for iterators over std::pair<const std::(w)?string, std::(w)?string>
  *
  * This is mainly used for wrapping map<string,string> and friends 
  * which happens to produce iterators over pair<const string, string>
@@ -347,50 +329,15 @@
 	size_t size = std::distance( first, last ) ;
 	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
 	SEXP names = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
-	size_t i = 0 ;
-	while( i < size ){
+	for( size_t i = 0; i < size ; i++, ++first){
 		SET_STRING_ELT( x, i, make_charsexp( first->second ) ) ;
-		
 		SET_STRING_ELT( names, i, make_charsexp( first->first) ) ;
-		
-		i++ ;
-		++first ;
 	}
 	::Rf_setAttrib( x, R_NamesSymbol, names ) ;
 	UNPROTECT(2) ; /* x, names */
 	return x ;
-}
-/**
- * Range based wrap for iterators over std::pair<const std::string, std::wstring>
- *
- * This is mainly used for wrapping map<string,wstring> and friends 
- * which happens to produce iterators over pair<const string, wstring>
- *
- * This produces a character vector containing copies of the 
- * string iterated over. The names of the vector is set to the keys
- * of the pair
- */
-template<typename InputIterator, typename T>
-inline SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, ::Rcpp::traits::r_type_pairstring_wstring_tag ){
-	size_t size = std::distance( first, last ) ;
-	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
-	SEXP names = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
-	size_t i = 0 ;
-	while( i < size ){
-		// a wstring
-		SET_STRING_ELT( x, i, make_charsexp(first->second) ) ;
-		
-		// a string
-		SET_STRING_ELT( names, i, make_charsexp(first->first) ) ;
-		
-		i++ ;
-		++first ;
-	}
-	::Rf_setAttrib( x, R_NamesSymbol, names ) ;
-	UNPROTECT(2) ; /* x, names */
-	return x ;
-}
 
+}
 // }}}
 
 /**
@@ -453,35 +400,19 @@
 }
 
 /**
- * primitive wrap for types that can be converted implicitely to std::string
+ * primitive wrap for types that can be converted implicitely to std::string or std::wstring
  * 
- * This produces a character vector of length 1 containing the std::string
+ * This produces a character vector of length 1 containing the std::string or wstring
  */
 template <typename T>
 inline SEXP primitive_wrap__impl( const T& object, ::Rcpp::traits::r_type_string_tag){
 	SEXP x = PROTECT( ::Rf_allocVector( STRSXP, 1) ) ;
-	std::string y = object ; /* give a chance to implicit conversion */
-	SET_STRING_ELT( x, 0, make_charsexp(y) ) ;
-	UNPROTECT(1) ;
-	return x; 
-}
-
-/**
- * primitive wrap for types that can be converted implicitely to std::wstring
- * 
- * This produces a character vector of length 1 containing the std::wstring
- */
-template <typename T>
-inline SEXP primitive_wrap__impl( const T& object, ::Rcpp::traits::r_type_wstring_tag){
-	SEXP x = PROTECT( ::Rf_allocVector( STRSXP, 1) ) ;
 	SET_STRING_ELT( x, 0, make_charsexp(object) ) ;
 	UNPROTECT(1) ;
 	return x; 
 }
 
 
-
-
 /**
  * called when T is a primitive type : int, bool, double, std::string, etc ...
  * This uses the Rcpp::traits::r_type_traits on the type T to perform
@@ -609,25 +540,7 @@
 	UNPROTECT(2) ;
 	return res ;
 }
-template <typename T>
-inline SEXP wrap_dispatch_matrix_not_logical( const T& object, ::Rcpp::traits::r_type_wstring_tag ){
-	int nr = object.nrow(), nc = object.ncol() ;
-	SEXP res = PROTECT( Rf_allocVector( STRSXP, nr*nc ) ) ;
-	
-	int k=0 ;
-	for( int j=0; j<nc; j++)
-		for( int i=0; i<nr; i++, k++)
-			SET_STRING_ELT( res, k, make_charsexp(object(i,j)) ) ;
-	SEXP dim = PROTECT( Rf_allocVector( INTSXP, 2) ) ;
-	INTEGER(dim)[0] = nr ;
-	INTEGER(dim)[1] = nc ;
-	Rf_setAttrib( res, R_DimSymbol , dim ) ;
-	UNPROTECT(2) ;
-	return res ;
-}
 
-
-
 template <typename T>
 inline SEXP wrap_dispatch_matrix_not_logical( const T& object, ::Rcpp::traits::r_type_generic_tag ){
 	int nr = object.nrow(), nc = object.ncol() ;
@@ -719,16 +632,6 @@
 	UNPROTECT(1) ;
 	return x ;
 }
-template <typename T, typename elem_type>
-inline SEXP wrap_dispatch_importer__impl( const T& object, ::Rcpp::traits::r_type_wstring_tag ){
-	int size = object.size() ;
-	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) );
-	for( int i=0; i<size; i++){
-		SET_STRING_ELT( x, i, make_charsexp(object.get(i)) ) ;
-	}
-	UNPROTECT(1) ;
-	return x ;
-}
 
 template <typename T, typename elem_type>
 inline SEXP wrap_dispatch_importer__impl( const T& object, ::Rcpp::traits::r_type_generic_tag ){
@@ -858,22 +761,6 @@
 	UNPROTECT(2); /* out, dims */
 	return out ;
 }
-template <typename value_type, typename InputIterator> 
-inline SEXP rowmajor_wrap__dispatch( InputIterator first, int nrow, int ncol, ::Rcpp::traits::r_type_wstring_tag ){
-	SEXP out = PROTECT( ::Rf_allocVector( STRSXP, nrow * ncol) );
-	int i=0, j=0 ;
-	for( j=0; j<ncol; j++){
-		for( i=0; i<nrow; i++, ++first ){
-			SET_STRING_ELT( out, j + ncol*i, make_charsexp(*first) ) ;
-		}
-	}
-	SEXP dims = PROTECT( ::Rf_allocVector( INTSXP, 2) ); 
-	INTEGER(dims)[0] = nrow; 
-	INTEGER(dims)[1] = ncol; 
-	::Rf_setAttrib( out, R_DimSymbol, dims) ;
-	UNPROTECT(2); /* out, dims */
-	return out ;
-}
 
 template <typename value_type, typename InputIterator> 
 inline SEXP primitive_rowmajor_wrap__dispatch( InputIterator first, int nrow, int ncol, ::Rcpp::traits::false_type ){

Added: pkg/Rcpp/inst/include/Rcpp/traits/char_type.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/traits/char_type.h	                        (rev 0)
+++ pkg/Rcpp/inst/include/Rcpp/traits/char_type.h	2013-02-04 14:43:57 UTC (rev 4237)
@@ -0,0 +1,45 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+/* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */
+//
+// char_type.h: Rcpp R/C++ interface class library -- 
+//
+// Copyright (C) 2013 Dirk Eddelbuettel and Romain Francois
+// Copyright (C) 2013 Rice University
+//
+// This file is part of Rcpp.
+//
+// Rcpp is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Rcpp is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//                         
+// You should have received a copy of the GNU General Public License
+// along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef Rcpp__traits__char_type__h
+#define Rcpp__traits__char_type__h
+
+namespace Rcpp{
+namespace traits{
+
+    template <typename T>
+    struct char_type {
+    	typedef typename T::value_type type ; 
+    } ;
+	
+    template <> struct char_type< const wchar_t* > {
+    	typedef wchar_t type ;	
+    } ;
+    template <> struct char_type< const char* > {
+    	typedef char type ;
+    } ;
+    
+} // traits
+} // Rcpp
+
+#endif

Modified: pkg/Rcpp/inst/include/Rcpp/traits/r_type_traits.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/traits/r_type_traits.h	2013-02-04 11:36:27 UTC (rev 4236)
+++ pkg/Rcpp/inst/include/Rcpp/traits/r_type_traits.h	2013-02-04 14:43:57 UTC (rev 4237)
@@ -40,12 +40,6 @@
 struct r_type_string_tag{} ;
 
 /**
- * Identifies that the associated type can be implicitely converted
- * to a std::wstring
- */
-struct r_type_wstring_tag{} ;
-
-/**
  * Default
  */
 struct r_type_generic_tag{} ;
@@ -57,16 +51,11 @@
 struct r_type_pairstring_primitive_tag{} ;
 
 /**
- * Identifies that the associated type is pair<const std::string,std::string>
+ * Identifies that the associated type is pair<const std::(w)?string,std::(w)?string>
  */
 struct r_type_pairstring_string_tag{} ;
 
 /**
- * Identifies that the associated type is pair<const std::string,std::wstring>
- */
-struct r_type_pairstring_wstring_tag{} ;
-
-/**
  * Indentifies pair<const std::string,T>
  */
 struct r_type_pairstring_generic_tag{} ;
@@ -110,9 +99,9 @@
 template<> struct r_type_traits< std::pair<const std::string,Rcomplex> >{ typedef r_type_pairstring_primitive_tag r_category ; } ;
 template<> struct r_type_traits< std::pair<const std::string,bool> >{ typedef r_type_pairstring_primitive_tag r_category ; } ;
 template<> struct r_type_traits< std::pair<const std::string,std::string> >{ typedef r_type_pairstring_string_tag r_category ; } ;
-template<> struct r_type_traits< std::pair<const std::string,std::wstring> >{ typedef r_type_pairstring_wstring_tag r_category ; } ;
+template<> struct r_type_traits< std::pair<const std::string,std::wstring> >{ typedef r_type_pairstring_string_tag r_category ; } ;
 template<> struct r_type_traits< std::pair<const std::string,char> >{ typedef r_type_pairstring_string_tag r_category ; } ;
-template<> struct r_type_traits< std::pair<const std::string,wchar_t> >{ typedef r_type_pairstring_wstring_tag r_category ; } ;
+template<> struct r_type_traits< std::pair<const std::string,wchar_t> >{ typedef r_type_pairstring_string_tag r_category ; } ;
 
 template<> struct r_type_traits< std::pair<const std::string,unsigned int> >{ typedef r_type_pairstring_primitive_tag r_category ; } ;
 template<> struct r_type_traits< std::pair<const std::string,float> >{ typedef r_type_pairstring_primitive_tag r_category ; } ;
@@ -124,14 +113,14 @@
 template<> struct r_type_traits<Rcomplex>{ typedef r_type_primitive_tag r_category ; } ;
 template<> struct r_type_traits<bool>{ typedef r_type_primitive_tag r_category ; } ;
 template<> struct r_type_traits<std::string>{ typedef r_type_string_tag r_category ; } ;
-template<> struct r_type_traits<std::wstring>{ typedef r_type_wstring_tag r_category ; } ;
+template<> struct r_type_traits<std::wstring>{ typedef r_type_string_tag r_category ; } ;
 template<> struct r_type_traits<char>{ typedef r_type_string_tag r_category ; } ;
-template<> struct r_type_traits<wchar_t>{ typedef r_type_wstring_tag r_category ; } ;
+template<> struct r_type_traits<wchar_t>{ typedef r_type_string_tag r_category ; } ;
 
 template<> struct r_type_traits<unsigned int>{ typedef r_type_primitive_tag r_category ; } ;
 template<> struct r_type_traits<float>{ typedef r_type_primitive_tag r_category ; } ;
 template<> struct r_type_traits<const char*>{ typedef r_type_string_tag r_category ; } ;
-template<> struct r_type_traits<const wchar_t*>{ typedef r_type_wstring_tag r_category ; } ;
+template<> struct r_type_traits<const wchar_t*>{ typedef r_type_string_tag r_category ; } ;
 
 /* long */
 template<> struct r_type_traits<long>{ typedef r_type_primitive_tag r_category ; } ;

Modified: pkg/Rcpp/inst/include/Rcpp/traits/traits.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/traits/traits.h	2013-02-04 11:36:27 UTC (rev 4236)
+++ pkg/Rcpp/inst/include/Rcpp/traits/traits.h	2013-02-04 14:43:57 UTC (rev 4237)
@@ -26,6 +26,7 @@
 #include <Rcpp/traits/integral_constant.h>
 #include <Rcpp/traits/same_type.h>
 #include <Rcpp/traits/is_wide_string.h>
+#include <Rcpp/traits/char_type.h>
 #include <Rcpp/traits/named_object.h>
 #include <Rcpp/traits/is_convertible.h>
 #include <Rcpp/traits/has_iterator.h>



More information about the Rcpp-commits mailing list