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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Feb 4 12:36:27 CET 2013


Author: romain
Date: 2013-02-04 12:36:27 +0100 (Mon, 04 Feb 2013)
New Revision: 4236

Added:
   pkg/Rcpp/inst/include/Rcpp/traits/is_wide_string.h
Modified:
   pkg/Rcpp/ChangeLog
   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
   pkg/Rcpp/inst/include/RcppCommon.h
   pkg/Rcpp/src/api.cpp
Log:
move some logic about making CHARSXP to lower level to help more generic code

Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog	2013-02-03 13:33:36 UTC (rev 4235)
+++ pkg/Rcpp/ChangeLog	2013-02-04 11:36:27 UTC (rev 4236)
@@ -1,3 +1,10 @@
+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/internal/wrap.h : using make_charsexp, a more generic version
+        of charsexp_from_wstring.
+        
 2013-02-03 Romain Francois <romain at r-enthusiasts.com>
 
         * include/Rcpp/traits/wrap_type_traits.h : support for wrap( wstring )

Modified: pkg/Rcpp/inst/include/Rcpp/internal/wrap.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/internal/wrap.h	2013-02-03 13:33:36 UTC (rev 4235)
+++ pkg/Rcpp/inst/include/Rcpp/internal/wrap.h	2013-02-04 11:36:27 UTC (rev 4236)
@@ -40,6 +40,38 @@
 
 namespace internal{
 	
+	char* get_string_buffer() ;
+	
+	inline SEXP make_charsexp__impl__wstring( const wchar_t* data ){
+		char* buffer = get_string_buffer() ;
+		wcstombs( buffer, data, MAXELTSIZE ) ;
+		return Rf_mkChar(buffer) ;
+	}
+	inline SEXP make_charsexp__impl__wstring( const std::wstring& st ){
+		return make_charsexp__impl__wstring( st.data()) ;	
+	}
+	inline SEXP make_charsexp__impl__cstring( const char* data ){
+		return Rf_mkChar( data ) ;
+	}
+	inline SEXP make_charsexp__impl__cstring( const std::string& st ){
+		return make_charsexp__impl__cstring( st.c_str() ) ;
+	}
+	
+	template <typename T>
+	inline SEXP make_charsexp__impl( const T& s, Rcpp::traits::true_type ){
+		return make_charsexp__impl__wstring(s) ;
+	}
+	
+	template <typename T>
+	inline SEXP make_charsexp__impl( const T& s, Rcpp::traits::false_type ){
+		return make_charsexp__impl__cstring(s) ;
+	}
+	
+	template <typename T> 
+	inline SEXP make_charsexp( const T& s) {
+		return make_charsexp__impl<T>( s, typename Rcpp::traits::is_wide_string<T>::type() ) ;
+	}
+	
 	template <typename InputIterator> SEXP range_wrap(InputIterator first, InputIterator last) ;
 	template <typename InputIterator> SEXP rowmajor_wrap(InputIterator first, int nrow, int ncol) ;
 
@@ -163,10 +195,8 @@
 	size_t size = std::distance( first, last ) ;
 	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
 	size_t i = 0 ;
-	std::string buffer ;
 	while( i < size ){
-		buffer = *first ;
-		SET_STRING_ELT( x, i, Rf_mkChar( buffer.c_str()) ) ;
+		SET_STRING_ELT( x, i, make_charsexp(*first) ) ;
 		i++ ;
 		++first ;
 	}
@@ -184,10 +214,8 @@
 	size_t size = std::distance( first, last ) ;
 	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
 	size_t i = 0 ;
-	std::wstring buffer ;
 	while( i < size ){
-		buffer = *first ;
-		SET_STRING_ELT( x, i, charsexp_from_wstring(buffer) ) ;
+		SET_STRING_ELT( x, i, make_charsexp(*first) ) ;
 		i++ ;
 		++first ;
 	}
@@ -320,13 +348,10 @@
 	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
 	SEXP names = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
 	size_t i = 0 ;
-	std::string buffer ;
 	while( i < size ){
-		buffer = first->second ;
-		SET_STRING_ELT( x, i, Rf_mkChar( buffer.c_str()) ) ;
+		SET_STRING_ELT( x, i, make_charsexp( first->second ) ) ;
 		
-		buffer = first->first ;
-		SET_STRING_ELT( names, i, Rf_mkChar( buffer.c_str()) ) ;
+		SET_STRING_ELT( names, i, make_charsexp( first->first) ) ;
 		
 		i++ ;
 		++first ;
@@ -335,6 +360,37 @@
 	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 ;
+}
+
 // }}}
 
 /**
@@ -405,10 +461,11 @@
 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, Rf_mkChar(y.c_str()) ) ;
+	SET_STRING_ELT( x, 0, make_charsexp(y) ) ;
 	UNPROTECT(1) ;
 	return x; 
 }
+
 /**
  * primitive wrap for types that can be converted implicitely to std::wstring
  * 
@@ -417,7 +474,7 @@
 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, charsexp_from_wstring(object) ) ;
+	SET_STRING_ELT( x, 0, make_charsexp(object) ) ;
 	UNPROTECT(1) ;
 	return x; 
 }
@@ -544,7 +601,7 @@
 	int k=0 ;
 	for( int j=0; j<nc; j++)
 		for( int i=0; i<nr; i++, k++)
-			SET_STRING_ELT( res, k, object(i,j) ) ;
+			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 ;
@@ -560,7 +617,7 @@
 	int k=0 ;
 	for( int j=0; j<nc; j++)
 		for( int i=0; i<nr; i++, k++)
-			SET_STRING_ELT( res, k, charsexp_from_wstring(object(i,j)) ) ;
+			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 ;
@@ -656,10 +713,8 @@
 inline SEXP wrap_dispatch_importer__impl( const T& object, ::Rcpp::traits::r_type_string_tag ){
 	int size = object.size() ;
 	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) );
-	std::string buf ;
 	for( int i=0; i<size; i++){
-		buf = object.get(i) ;
-		SET_STRING_ELT( x, i, Rf_mkChar( buf.c_str() ) ) ;
+		SET_STRING_ELT( x, i, make_charsexp(object.get(i)) ) ;
 	}
 	UNPROTECT(1) ;
 	return x ;
@@ -668,10 +723,8 @@
 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 ) );
-	std::wstring buf ;
 	for( int i=0; i<size; i++){
-		buf = object.get(i) ;
-		SET_STRING_ELT( x, i, charsexp_from_wstring(buf) ) ;
+		SET_STRING_ELT( x, i, make_charsexp(object.get(i)) ) ;
 	}
 	UNPROTECT(1) ;
 	return x ;
@@ -793,11 +846,9 @@
 inline SEXP rowmajor_wrap__dispatch( InputIterator first, int nrow, int ncol, ::Rcpp::traits::r_type_string_tag ){
 	SEXP out = PROTECT( ::Rf_allocVector( STRSXP, nrow * ncol) );
 	int i=0, j=0 ;
-	std::string buffer ;
 	for( j=0; j<ncol; j++){
 		for( i=0; i<nrow; i++, ++first ){
-			buffer = *first ;
-			SET_STRING_ELT( out, j + ncol*i, ::Rf_mkChar(buffer.c_str()) ) ;
+			SET_STRING_ELT( out, j + ncol*i, make_charsexp(*first) ) ;
 		}
 	}
 	SEXP dims = PROTECT( ::Rf_allocVector( INTSXP, 2) ); 
@@ -811,11 +862,9 @@
 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 ;
-	std::wstring buffer ;
 	for( j=0; j<ncol; j++){
 		for( i=0; i<nrow; i++, ++first ){
-			buffer = *first ;
-			SET_STRING_ELT( out, j + ncol*i, charsexp_from_wstring(buffer) ) ;
+			SET_STRING_ELT( out, j + ncol*i, make_charsexp(*first) ) ;
 		}
 	}
 	SEXP dims = PROTECT( ::Rf_allocVector( INTSXP, 2) ); 

Added: pkg/Rcpp/inst/include/Rcpp/traits/is_wide_string.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/traits/is_wide_string.h	                        (rev 0)
+++ pkg/Rcpp/inst/include/Rcpp/traits/is_wide_string.h	2013-02-04 11:36:27 UTC (rev 4236)
@@ -0,0 +1,39 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+/* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */
+//
+// is_wide_string.h: Rcpp R/C++ interface class library -- traits to help wrap
+//
+// 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__is_wide_string__h
+#define Rcpp__traits__is_wide_string__h
+
+namespace Rcpp{
+namespace traits{
+
+    template <typename T>
+    struct is_wide_string : public same_type< typename T::value_type, wchar_t > {} ;
+	
+    template <> struct is_wide_string< const wchar_t* > : public true_type{} ;
+    template <> struct is_wide_string< const char* > : public false_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-03 13:33:36 UTC (rev 4235)
+++ pkg/Rcpp/inst/include/Rcpp/traits/r_type_traits.h	2013-02-04 11:36:27 UTC (rev 4236)
@@ -62,6 +62,11 @@
 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{} ;
@@ -105,7 +110,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,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,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 ; } ;

Modified: pkg/Rcpp/inst/include/Rcpp/traits/traits.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/traits/traits.h	2013-02-03 13:33:36 UTC (rev 4235)
+++ pkg/Rcpp/inst/include/Rcpp/traits/traits.h	2013-02-04 11:36:27 UTC (rev 4236)
@@ -25,6 +25,7 @@
 
 #include <Rcpp/traits/integral_constant.h>
 #include <Rcpp/traits/same_type.h>
+#include <Rcpp/traits/is_wide_string.h>
 #include <Rcpp/traits/named_object.h>
 #include <Rcpp/traits/is_convertible.h>
 #include <Rcpp/traits/has_iterator.h>

Modified: pkg/Rcpp/inst/include/RcppCommon.h
===================================================================
--- pkg/Rcpp/inst/include/RcppCommon.h	2013-02-03 13:33:36 UTC (rev 4235)
+++ pkg/Rcpp/inst/include/RcppCommon.h	2013-02-04 11:36:27 UTC (rev 4236)
@@ -90,8 +90,6 @@
     class String ;
 	namespace internal{
 		template <typename Class> SEXP make_new_object( Class* ptr ) ;	
-		
-		SEXP charsexp_from_wstring( const std::wstring& s) ;
 	}
 }	
 

Modified: pkg/Rcpp/src/api.cpp
===================================================================
--- pkg/Rcpp/src/api.cpp	2013-02-03 13:33:36 UTC (rev 4235)
+++ pkg/Rcpp/src/api.cpp	2013-02-04 11:36:27 UTC (rev 4236)
@@ -1654,10 +1654,9 @@
     return buff ;    
 }
 
-SEXP charsexp_from_wstring( const std::wstring& s){
+char* get_string_buffer(){
     static char buffer[MAXELTSIZE];
-    wcstombs( buffer, s.data(), MAXELTSIZE ) ;
-    return Rf_mkChar(buffer) ;    
+    return buffer ;    
 }
 
 // static const char* dropTrailing0(char *s, char cdec) {



More information about the Rcpp-commits mailing list