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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Wed Feb 10 10:03:47 CET 2010


Author: romain
Date: 2010-02-10 10:03:46 +0100 (Wed, 10 Feb 2010)
New Revision: 654

Modified:
   pkg/inst/ChangeLog
   pkg/inst/unitTests/runit.CharacterVector.R
   pkg/inst/unitTests/runit.GenericVector.R
   pkg/inst/unitTests/runit.IntegerVector.R
   pkg/src/CharacterVector.cpp
   pkg/src/Rcpp/CharacterVector.h
   pkg/src/Rcpp/SEXP_Vector.h
   pkg/src/Rcpp/SimpleVector.h
   pkg/src/Rcpp/VectorBase.h
   pkg/src/SEXP_Vector.cpp
   pkg/src/VectorBase.cpp
Log:
names based indexing (only 1d for now) 

Modified: pkg/inst/ChangeLog
===================================================================
--- pkg/inst/ChangeLog	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/inst/ChangeLog	2010-02-10 09:03:46 UTC (rev 654)
@@ -1,3 +1,19 @@
+2010-02-10  Romain Francois <romain at r-enthusiasts.com>
+
+	* src/Rcpp/VectorBase.h: VectorBase gains a version of 
+	offset to support retrieving the offset of a given name of a
+	vector: offset( const std::string& name)
+	
+	* src/Rcpp/SimpleVector.h : uses the new offset to perform
+	names based indexing (FR #808)
+	* src/Rcpp/SEXP_Vector.h: same
+	* src/Rcpp/CharacterVector.h: same
+	
+	* inst/unitTests/runit.GenericVector.R: unit tests for names
+	based indexing
+	* inst/unitTests/runit.IntegerVector.R: same
+	* inst/unitTests/runit.CharacterVector.R: same
+
 2010-02-09  Dirk Eddelbuettel  <edd at debian.org>
 
 	* inst/skeleton/Makevars: Use $R_HOME/bin indirection

Modified: pkg/inst/unitTests/runit.CharacterVector.R
===================================================================
--- pkg/inst/unitTests/runit.CharacterVector.R	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/inst/unitTests/runit.CharacterVector.R	2010-02-10 09:03:46 UTC (rev 654)
@@ -213,3 +213,14 @@
 	checkEquals( x, c("foo", "bar", "bling"), msg = "reverse" )
 }
 
+test.CharacterVector.names.indexing <- function(){
+	funx <- cfunction(signature(x = "character"), '
+		CharacterVector y(x) ;
+		std::string foo( y["foo"] ) ;
+		return wrap(foo) ;
+	;', Rcpp = TRUE, includes = "using namespace Rcpp;" )
+	x <- c( foo = "foo", bar = "bar" )
+	checkEquals( funx(x), "foo", msg = "CharacterVector names based indexing" )
+}
+
+

Modified: pkg/inst/unitTests/runit.GenericVector.R
===================================================================
--- pkg/inst/unitTests/runit.GenericVector.R	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/inst/unitTests/runit.GenericVector.R	2010-02-10 09:03:46 UTC (rev 654)
@@ -138,6 +138,18 @@
 		list( x = 26L, y = 26L, z = 4L), 
 		msg = "c++ version of lapply" )
 	
+}
+
+test.List.name.indexing <- function(){
 	
+	funx <- cfunction( signature(x = "data.frame"), 
+	'
+	List df(x) ;
+	IntegerVector df_x = df["x"] ;
+	int res = std::accumulate( df_x.begin(), df_x.end(), 0 ) ;
+	return wrap(res);
+	', Rcpp = TRUE, includes = "using namespace Rcpp;" )
+	d <- data.frame( x = 1:10, y = letters[1:10] )
+	checkEquals( funx( d ), sum(1:10), msg = "List names based indexing" )
 }
 

Modified: pkg/inst/unitTests/runit.IntegerVector.R
===================================================================
--- pkg/inst/unitTests/runit.IntegerVector.R	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/inst/unitTests/runit.IntegerVector.R	2010-02-10 09:03:46 UTC (rev 654)
@@ -144,3 +144,13 @@
 		msg = "Vector::names get" )
 }
 
+test.IntegerVector.names.indexing <- function(){
+	funx <- cfunction(signature(x = "integer"), '
+		IntegerVector y(x) ;
+		return wrap( y["foo"]) ;
+	', Rcpp = TRUE, includes = "using namespace Rcpp;"  )
+	x <- c( "foo" = 1L, "bar" = 2L )
+	checkEquals( funx( x ), 1L, msg = "IntegerVector names based indexing" )
+	
+}
+

Modified: pkg/src/CharacterVector.cpp
===================================================================
--- pkg/src/CharacterVector.cpp	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/src/CharacterVector.cpp	2010-02-10 09:03:46 UTC (rev 654)
@@ -68,8 +68,8 @@
 	return STRING_ELT( parent, index ) ;
 }
 
-CharacterVector::StringProxy::operator const char*() const {
-	return /*const_cast<char*>*/( CHAR(STRING_ELT( parent, index )) );
+CharacterVector::StringProxy::operator /*const*/ char*() const {
+	return const_cast<char*>( CHAR(STRING_ELT( parent, index )) );
 }
 
 // CharacterVector::StringProxy::operator std::string() const {
@@ -109,10 +109,19 @@
 	return StringProxy(const_cast<CharacterVector&>(*this), offset(i) ) ;
 }                                          
 
+CharacterVector::StringProxy CharacterVector::operator[](const std::string& name) throw(index_out_of_bounds) {
+	return StringProxy(*this, offset(name) ) ;
+}
+
+const CharacterVector::StringProxy CharacterVector::operator[](const std::string& name) const throw(index_out_of_bounds){
+	return StringProxy(const_cast<CharacterVector&>(*this), offset(name) ) ;
+}                                          
+
 CharacterVector::StringProxy CharacterVector::operator[](int i) throw(index_out_of_bounds) {
 	return StringProxy(*this, offset(i) ) ;
 }
 
+
 CharacterVector::StringProxy CharacterVector::operator()( const size_t& i) throw(index_out_of_bounds){
 	return StringProxy(*this, offset(i) ) ;
 }

Modified: pkg/src/Rcpp/CharacterVector.h
===================================================================
--- pkg/src/Rcpp/CharacterVector.h	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/src/Rcpp/CharacterVector.h	2010-02-10 09:03:46 UTC (rev 654)
@@ -91,7 +91,7 @@
 		 * element this proxy refers to and convert it to a 
 		 * C string
 		 */
-		operator const char*() const ;
+		operator /*const */ char*() const ;
 		
 		/**
 		 * Prints the element this proxy refers to to an 
@@ -227,6 +227,9 @@
 	 */
 	StringProxy operator[]( int i ) throw(index_out_of_bounds);
 
+	const StringProxy operator[]( const std::string& name) const throw(index_out_of_bounds); 
+	StringProxy operator[]( const std::string& name ) throw(index_out_of_bounds);
+
 	friend class StringProxy;
 	
 	/* '(' indexing */

Modified: pkg/src/Rcpp/SEXP_Vector.h
===================================================================
--- pkg/src/Rcpp/SEXP_Vector.h	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/src/Rcpp/SEXP_Vector.h	2010-02-10 09:03:46 UTC (rev 654)
@@ -104,22 +104,21 @@
 	
 	SEXP_Vector_Base() ; 
 	
-	const Proxy operator[]( int i ) const throw(index_out_of_bounds){
+	inline const Proxy operator[]( int i ) const throw(index_out_of_bounds){
 		return Proxy(const_cast<SEXP_Vector_Base&>(*this), offset(i)) ;
 	}
-	Proxy operator[]( int i ) throw(index_out_of_bounds){
+	inline Proxy operator[]( int i ) throw(index_out_of_bounds){
 		return Proxy(*this, offset(i) ) ; 
 	}
 	
+	const Proxy operator[]( const std::string& name) const ; 
+	Proxy operator[](const std::string& name) ;
+    	
 	inline iterator begin() { return iterator(*this, 0) ; }
 	inline iterator end() { return iterator(*this, size() ) ; }
 	
-	Proxy operator()( const size_t& i) throw(index_out_of_bounds){
-		return Proxy(*this, offset(i) ) ;
-	}
-	Proxy operator()( const size_t& i, const size_t& j) throw(index_out_of_bounds,not_a_matrix){
-		return Proxy(*this, offset(i,j) ) ;
-	}
+	Proxy operator()( const size_t& i) throw(index_out_of_bounds) ; 
+	Proxy operator()( const size_t& i, const size_t& j) throw(index_out_of_bounds,not_a_matrix) ;
 	
 	friend class Proxy;
 	friend class iterator ;

Modified: pkg/src/Rcpp/SimpleVector.h
===================================================================
--- pkg/src/Rcpp/SimpleVector.h	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/src/Rcpp/SimpleVector.h	2010-02-10 09:03:46 UTC (rev 654)
@@ -79,13 +79,18 @@
 #endif
 
 	inline reference operator[]( const int& i ){ return start[i] ; }
+	inline reference operator[]( const std::string& name) {
+		return start[ offset(name) ];
+	}
 	inline iterator begin() const{ return start ; }
 	inline iterator end() const{ return start+Rf_length(m_sexp); }
 	
 	inline reference operator()( const size_t& i) throw(RObject::index_out_of_bounds){
 		return start[ offset(i) ] ;
 	}
-	
+	inline reference operator()( const std::string& name) {
+		return start[ offset(name) ];
+	}
 	inline reference operator()( const size_t& i, const size_t& j) throw(VectorBase::not_a_matrix,RObject::index_out_of_bounds){
 		return start[ offset(i,j) ] ;
 	}

Modified: pkg/src/Rcpp/VectorBase.h
===================================================================
--- pkg/src/Rcpp/VectorBase.h	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/src/Rcpp/VectorBase.h	2010-02-10 09:03:46 UTC (rev 654)
@@ -61,6 +61,8 @@
      */
     size_t offset(const size_t& i) const throw(RObject::index_out_of_bounds);
     
+    R_len_t offset(const std::string& name) const throw(RObject::index_out_of_bounds) ;
+    
     /* TODO: 3 dimensions, ... n dimensions through variadic templates */
     
     class NamesProxy {

Modified: pkg/src/SEXP_Vector.cpp
===================================================================
--- pkg/src/SEXP_Vector.cpp	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/src/SEXP_Vector.cpp	2010-02-10 09:03:46 UTC (rev 654)
@@ -65,7 +65,21 @@
 /* SEXP_Vector_Base */
 SEXP_Vector_Base::SEXP_Vector_Base() : VectorBase(){}
 
+SEXP_Vector_Base::Proxy SEXP_Vector_Base::operator()( const size_t& i) throw(index_out_of_bounds) {
+	return Proxy(*this, offset(i) ) ;
+}
+SEXP_Vector_Base::Proxy SEXP_Vector_Base::operator()( const size_t& i, const size_t& j) throw(index_out_of_bounds,not_a_matrix){
+	return Proxy(*this, offset(i,j) ) ;
+}
 
+const SEXP_Vector_Base::Proxy SEXP_Vector_Base::operator[]( const std::string& name) const {
+	return Proxy( const_cast<SEXP_Vector_Base&>(*this), offset(name) ) ;
+}
+SEXP_Vector_Base::Proxy SEXP_Vector_Base::operator[](const std::string& name) {
+	return Proxy(*this, offset(name) ) ;
+}
+    	
+
 } // namespace Rcpp
 
 namespace std{

Modified: pkg/src/VectorBase.cpp
===================================================================
--- pkg/src/VectorBase.cpp	2010-02-09 18:54:23 UTC (rev 653)
+++ pkg/src/VectorBase.cpp	2010-02-10 09:03:46 UTC (rev 654)
@@ -41,6 +41,20 @@
     	    if( static_cast<R_len_t>(i) >= Rf_length(m_sexp) ) throw RObject::index_out_of_bounds() ;
     	    return i ;
     	}
+    	
+    	R_len_t VectorBase::offset(const std::string& name) const throw(RObject::index_out_of_bounds){
+    		SEXP names = RCPP_GET_NAMES( m_sexp ) ;
+    		if( names == R_NilValue ) throw RObject::index_out_of_bounds(); 
+    		R_len_t n=size() ;
+    		for( R_len_t i=0; i<n; ++i){
+    			if( ! name.compare( CHAR(STRING_ELT(names, i)) ) ){
+    				return i ;
+    			}
+    		}
+    		throw RObject::index_out_of_bounds() ;
+    		return -1 ; /* -Wall */
+    	}
+    	
 
     	VectorBase::NamesProxy::NamesProxy( const VectorBase& v) : parent(v){} ;
     	VectorBase::NamesProxy& VectorBase::NamesProxy::operator=( const NamesProxy& rhs){



More information about the Rcpp-commits mailing list