[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