[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