[Rcpp-commits] r487 - in pkg: . inst inst/unitTests src src/Rcpp

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Wed Jan 27 20:46:11 CET 2010


Author: romain
Date: 2010-01-27 20:46:10 +0100 (Wed, 27 Jan 2010)
New Revision: 487

Modified:
   pkg/DESCRIPTION
   pkg/inst/ChangeLog
   pkg/inst/unitTests/runit.CharacterVector.R
   pkg/src/CharacterVector.cpp
   pkg/src/Rcpp/CharacterVector.h
Log:
CharacterVector gains range based constructor and range based assign function, modelled after vector<string>

Modified: pkg/DESCRIPTION
===================================================================
--- pkg/DESCRIPTION	2010-01-27 15:50:01 UTC (rev 486)
+++ pkg/DESCRIPTION	2010-01-27 19:46:10 UTC (rev 487)
@@ -1,6 +1,6 @@
 Package: Rcpp
 Title: Rcpp R/C++ interface package
-Version: 0.7.3.3
+Version: 0.7.3.4
 Date: $Date$
 Author: Dirk Eddelbuettel and Romain Francois, with contributions 
  by Simon Urbanek and David Reiss; based on code written during 

Modified: pkg/inst/ChangeLog
===================================================================
--- pkg/inst/ChangeLog	2010-01-27 15:50:01 UTC (rev 486)
+++ pkg/inst/ChangeLog	2010-01-27 19:46:10 UTC (rev 487)
@@ -1,8 +1,15 @@
 2010-01-27  Romain Francois <francoisromain at free.fr>
 
-	* src/Rcpp/CharacterVector.h: CharacterVector::StringProxy
-	gains implicit conversion to std::string
+	* src/Rcpp/CharacterVector.h: CharacterVector gains a default
+	constructor
 	
+	* src/Rcpp/CharacterVector.h: CharacterVector gains range
+	constructors and range based assign methods facilitating 
+	construction from iterators
+	
+	* inst/unitTests/runit.CharacterVector.R: unit tests for assign
+	and range based constructors
+
 	* src/Rcpp/CharacterVector.h: CharacterVector::StringProxy
 	gets a printing operator <<(std::ostream& )
 

Modified: pkg/inst/unitTests/runit.CharacterVector.R
===================================================================
--- pkg/inst/unitTests/runit.CharacterVector.R	2010-01-27 15:50:01 UTC (rev 486)
+++ pkg/inst/unitTests/runit.CharacterVector.R	2010-01-27 19:46:10 UTC (rev 487)
@@ -95,3 +95,50 @@
 		msg = "matrix indexing lhs" )
 }
 
+test.CharacterVector.assign <- function(){
+	
+	funx <- cfunction(signature(), '
+		const char* x[] = { "foo", "bar", "bling", "boom" } ;
+		CharacterVector y ;
+		y.assign( x, x+4 ) ;
+		return y;
+	', Rcpp = TRUE, includes = "using namespace Rcpp;"  )
+	checkEquals( funx(), c("foo", "bar", "bling", "boom"), msg = "assign(char**, char**)" )
+	
+	
+	funx <- cfunction(signature(), '
+		std::vector<std::string> vec(4) ;
+		vec[0] = "foo";
+		vec[1] = "bar";
+		vec[2] = "bling";
+		vec[3] = "boom" ;
+		CharacterVector y ;
+		y.assign( vec.begin(), vec.end() ) ;
+		return y;
+	', Rcpp = TRUE, includes = "using namespace Rcpp;"  )
+	checkEquals( funx(), c("foo", "bar", "bling", "boom"), msg = "assign(char**, char**)" )
+	
+}
+
+test.CharacterVector.range.constructors <- function(){
+
+	funx <- cfunction(signature(), '
+		const char* x[] = { "foo", "bar", "bling", "boom" } ;
+		CharacterVector y( x, x+4 ) ;
+		return y;
+	', Rcpp = TRUE, includes = "using namespace Rcpp;"  )
+	checkEquals( funx(), c("foo", "bar", "bling", "boom"), msg = "assign(char**, char**)" )
+	
+	
+	funx <- cfunction(signature(), '
+		std::vector<std::string> vec(4) ;
+		vec[0] = "foo";
+		vec[1] = "bar";
+		vec[2] = "bling";
+		vec[3] = "boom" ;
+		CharacterVector y( vec.begin(), vec.end() ) ;
+		return y;
+	', Rcpp = TRUE, includes = "using namespace Rcpp;"  )
+	checkEquals( funx(), c("foo", "bar", "bling", "boom"), msg = "assign(char**, char**)" )
+}
+

Modified: pkg/src/CharacterVector.cpp
===================================================================
--- pkg/src/CharacterVector.cpp	2010-01-27 15:50:01 UTC (rev 486)
+++ pkg/src/CharacterVector.cpp	2010-01-27 19:46:10 UTC (rev 487)
@@ -22,24 +22,26 @@
 #include <Rcpp/CharacterVector.h>
 
 namespace Rcpp{
+
+CharacterVector::CharacterVector() : VectorBase(){}
 	
-	CharacterVector::CharacterVector(SEXP x) throw(not_compatible) : VectorBase() {
-		SEXP y = r_cast<STRSXP>( x) ;
-		setSEXP( y ) ;
-	}
+CharacterVector::CharacterVector(SEXP x) throw(not_compatible) : VectorBase() {
+	SEXP y = r_cast<STRSXP>( x) ;
+	setSEXP( y ) ;
+}
+
+CharacterVector::CharacterVector(const size_t& size) : VectorBase(){
+	setSEXP( Rf_allocVector( STRSXP, size ) ) ;
+}
+
+CharacterVector::CharacterVector( const std::string& x) : VectorBase() {
+	setSEXP( Rf_mkString(x.c_str()) ) ;
+}
+
+CharacterVector::CharacterVector( const std::vector<std::string>& x): VectorBase() {
+	assign( x.begin(), x.end() ) ;
+}
 	
-	CharacterVector::CharacterVector(const size_t& size) : VectorBase(){
-		setSEXP( Rf_allocVector( STRSXP, size ) ) ;
-	}
-	
-	CharacterVector::CharacterVector( const std::string& x) : VectorBase() {
-		setSEXP( Rf_mkString(x.c_str()) ) ;
-	}
-	
-	CharacterVector::CharacterVector( const std::vector<std::string>& x): VectorBase() {
-		fill( x.begin(), x.size() ) ;
-	}
-	
 
 /* proxy stuff */
 
@@ -54,10 +56,6 @@
 	return const_cast<char*>( CHAR(STRING_ELT( parent, index )) );
 }
 
-CharacterVector::StringProxy::operator std::string() const {
-	return std::string( CHAR(STRING_ELT( parent, index )) );
-}
-
 CharacterVector::StringProxy& CharacterVector::StringProxy::operator=( const StringProxy& rhs){
 	SET_STRING_ELT( parent, index, STRING_ELT( rhs.parent, rhs.index) ) ;
 	return *this ;
@@ -89,7 +87,7 @@
 
 const CharacterVector::StringProxy CharacterVector::operator[](int i) const throw(index_out_of_bounds){
 	return StringProxy(const_cast<CharacterVector&>(*this), offset(i) ) ;
-}
+}                                          
 
 CharacterVector::StringProxy CharacterVector::operator[](int i) throw(index_out_of_bounds) {
 	return StringProxy(*this, offset(i) ) ;
@@ -103,4 +101,22 @@
 	return StringProxy(*this, offset(i,j) ) ;
 }
 
+void CharacterVector::assign( const char** first, const char** last){
+	size_t size = std::distance( first, last ) ;
+	SEXP x = m_sexp ;
+	bool update = false ;
+	if( length() != size ){
+		x = Rf_allocVector( STRSXP, size ) ;
+		update = true ;
+	}
+	for( size_t i=0; i<size; i++, ++first){
+		SET_STRING_ELT( x, i, Rf_mkChar(*first)) ;
+	}
+	if( update ) setSEXP( x ) ;
+}
+	
+CharacterVector::CharacterVector( const char** first, const char** last) : VectorBase(){
+	assign( first, last ) ;
+}
+
 } // namespace 

Modified: pkg/src/Rcpp/CharacterVector.h
===================================================================
--- pkg/src/Rcpp/CharacterVector.h	2010-01-27 15:50:01 UTC (rev 486)
+++ pkg/src/Rcpp/CharacterVector.h	2010-01-27 19:46:10 UTC (rev 487)
@@ -47,7 +47,6 @@
 		/* rvalue use */
 		operator SEXP() const ;
 		operator char*() const ;
-		operator std::string() const ;
 		
 		/* printing */
 		friend std::ostream& operator<<(std::ostream& os, const StringProxy& proxy);
@@ -57,14 +56,22 @@
 		int index ;
 	} ;
 
+	CharacterVector() ;
 	CharacterVector(SEXP x) throw(not_compatible);
 	CharacterVector( const size_t& size) ;
 	CharacterVector( const std::string& x );
 	CharacterVector( const std::vector<std::string>& x );
 	
+	CharacterVector( const char** first, const char** last) ;
+	
+	template <typename InputIterator>
+	CharacterVector( InputIterator first, InputIterator last): VectorBase() {
+		assign( first, last ) ;
+	}
+	
 #ifdef HAS_INIT_LISTS
 	CharacterVector( std::initializer_list<std::string> list ) : VectorBase() {
-		fill( list.begin(), list.size() ) ;
+		assign( list.begin(), list.size() ) ;
 	}
 #endif
 
@@ -77,16 +84,23 @@
 	StringProxy operator()( const size_t& i) throw(index_out_of_bounds) ;
 	StringProxy operator()( const size_t& i, const size_t& j) throw(index_out_of_bounds,not_a_matrix) ;
 
-private:
+	void assign( const char** first, const char** last) ; 
+	
 	template <typename InputIterator>
-	void fill(InputIterator first, size_t size ){
-		SEXP x = PROTECT( Rf_allocVector( STRSXP, size) ) ;
-		for( size_t i=0; i<size; ++i, ++first ){
-			SET_STRING_ELT( x, i, Rf_mkChar(first->c_str()) ) ;
+	void assign( InputIterator first, InputIterator last){
+		size_t size = std::distance( first, last ) ;
+		SEXP x = m_sexp ;
+		bool update = false ;
+		if( Rf_isNull(m_sexp) || length() != size ){
+			x = Rf_allocVector( STRSXP, size ) ;
+			update = true ;
 		}
-		setSEXP( x );
-		UNPROTECT(1) ;
+		for( size_t i=0; i<size; i++, ++first){
+			SET_STRING_ELT( x, i, Rf_mkChar(first->c_str())) ;
+		}
+		if( update ) setSEXP(x) ;
 	}
+
 } ;
 
 typedef CharacterVector StringVector ;



More information about the Rcpp-commits mailing list