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

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Tue Feb 9 11:34:16 CET 2010


Author: romain
Date: 2010-02-09 11:34:16 +0100 (Tue, 09 Feb 2010)
New Revision: 646

Modified:
   pkg/DESCRIPTION
   pkg/inst/ChangeLog
   pkg/inst/unitTests/runit.CharacterVector.R
   pkg/src/CharacterVector.cpp
   pkg/src/Rcpp/CharacterVector.h
Log:
+ CharacterVector::iterator

Modified: pkg/DESCRIPTION
===================================================================
--- pkg/DESCRIPTION	2010-02-09 08:11:20 UTC (rev 645)
+++ pkg/DESCRIPTION	2010-02-09 10:34:16 UTC (rev 646)
@@ -1,6 +1,6 @@
 Package: Rcpp
 Title: Rcpp R/C++ interface package
-Version: 0.7.5
+Version: 0.7.5.1
 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-02-09 08:11:20 UTC (rev 645)
+++ pkg/inst/ChangeLog	2010-02-09 10:34:16 UTC (rev 646)
@@ -1,3 +1,12 @@
+2010-02-09  Romain Francois <romain at r-enthusiasts.com>
+
+	* src/Rcpp/CharacterVector.h: CharacterVector gains a random
+	access iterator, begin() and end() to support STL algorithms. 
+	The iterator dereferences to a StringProxy
+
+	* src/Rcpp/RObject.h: remove RObject::asFoo methods which were 
+	deprecated in Rcpp 0.7.5. The alternative is to use Rcpp::as<Foo>
+
 2010-02-08  Dirk Eddelbuettel  <edd at debian.org>
 
 	* DESCRIPTION: Release 0.7.5

Modified: pkg/inst/unitTests/runit.CharacterVector.R
===================================================================
--- pkg/inst/unitTests/runit.CharacterVector.R	2010-02-09 08:11:20 UTC (rev 645)
+++ pkg/inst/unitTests/runit.CharacterVector.R	2010-02-09 10:34:16 UTC (rev 646)
@@ -166,4 +166,35 @@
 		msg = "CharacterVector( Dimension(2,3,4))" )
 }
 
-
+test.CharacterVector.iterator <- function(){
+	funx <- cfunction(signature(x = "character"), '
+		CharacterVector letters(x) ;
+		std::string res ;
+		CharacterVector::iterator first = letters.begin() ;
+		CharacterVector::iterator last = letters.end() ;
+		while( first != last ){
+			res += *first ;
+			++first ;
+		}
+		return wrap(res) ;
+	;
+		', Rcpp = TRUE, includes = "using namespace Rcpp;"  )
+	checkEquals( 
+		funx(letters), 
+		paste(letters, collapse=""), 
+		msg = "CharacterVector::iterator explicit looping" )
+	
+	funx <- cfunction(signature(x = "character"), '
+		CharacterVector letters(x) ;
+		std::string res( 
+			std::accumulate( 
+				letters.begin(), letters.end(), std::string() ) ) ;
+		return wrap(res) ;
+	;
+		', Rcpp = TRUE, includes = "using namespace Rcpp;" )
+	checkEquals( 
+		funx(letters), 
+		paste(letters, collapse=""), 
+		msg = "CharacterVector::iterator using std::accumulate" )
+	
+}

Modified: pkg/src/CharacterVector.cpp
===================================================================
--- pkg/src/CharacterVector.cpp	2010-02-09 08:11:20 UTC (rev 645)
+++ pkg/src/CharacterVector.cpp	2010-02-09 10:34:16 UTC (rev 646)
@@ -61,14 +61,21 @@
 CharacterVector::StringProxy::StringProxy(CharacterVector& v, int i) :
 	parent(v), index(i){}
 
+CharacterVector::StringProxy::StringProxy(const StringProxy& other) :
+	parent(other.parent), index(other.index){}
+
 CharacterVector::StringProxy::operator SEXP() const{
 	return STRING_ELT( parent, index ) ;
 }
 
-CharacterVector::StringProxy::operator 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 {
+// 	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 ;
@@ -114,4 +121,72 @@
 	return StringProxy(*this, offset(i,j) ) ;
 }
 
+/* iterator  */
+
+CharacterVector::iterator::iterator(CharacterVector& object, int index_ ) : 
+	proxy(object,index_) {};
+
+CharacterVector::iterator& CharacterVector::iterator::operator++(){
+	proxy.move(1) ;
+	return *this ;
+}
+
+CharacterVector::iterator& CharacterVector::iterator::operator++(int){
+	proxy.move(1) ;
+	return *this ;
+}
+
+CharacterVector::iterator& CharacterVector::iterator::operator--(){
+	proxy.move(-1) ;
+	return *this ;
+}
+
+CharacterVector::iterator& CharacterVector::iterator::operator--(int){
+	proxy.move(-1) ;
+	return *this ;
+}
+
+CharacterVector::iterator CharacterVector::iterator::operator+( difference_type n) const{
+	return iterator( proxy.parent, proxy.index+n) ;    
+}
+
+CharacterVector::iterator CharacterVector::iterator::operator-( difference_type n) const{
+	return iterator( proxy.parent, proxy.index-n) ;
+}
+
+CharacterVector::iterator& CharacterVector::iterator::operator+=(difference_type n) {
+	proxy.move(n) ;
+	return *this ;
+}
+
+CharacterVector::iterator& CharacterVector::iterator::operator-=(difference_type n) {
+	proxy.move(-n) ;
+	return *this ;
+}
+
+CharacterVector::iterator::reference CharacterVector::iterator::operator*(){
+	return proxy ;
+}
+
+CharacterVector::iterator::pointer CharacterVector::iterator::operator->(){
+	return &proxy ;
+}
+
+bool CharacterVector::iterator::operator==( const CharacterVector::iterator& y){
+	return ( this->proxy.index == y.proxy.index ) && ( this->proxy.parent == y.proxy.parent );
+}
+
+bool CharacterVector::iterator::operator!=( const CharacterVector::iterator& y){
+	return ( this->proxy.index != y.proxy.index ) || ( this->proxy.parent != y.proxy.parent );
+}
+
+CharacterVector::iterator::difference_type CharacterVector::iterator::operator-(
+		const CharacterVector::iterator& y ){
+	return y.proxy.index - this->proxy.index ;
+}
+
+std::string operator+( const std::string& x, const CharacterVector::StringProxy& y ){
+	return x + static_cast<const char*>(y) ;
+}
+
 } // namespace 

Modified: pkg/src/Rcpp/CharacterVector.h
===================================================================
--- pkg/src/Rcpp/CharacterVector.h	2010-02-09 08:11:20 UTC (rev 645)
+++ pkg/src/Rcpp/CharacterVector.h	2010-02-09 10:34:16 UTC (rev 646)
@@ -35,6 +35,8 @@
 class CharacterVector : public VectorBase {     
 public:
 
+	class iterator ;
+	
 	/**
 	 * Proxy object that can be used to get or set the value
 	 * a single value of the character vector
@@ -48,6 +50,7 @@
 		 * @param index index 
 		 */
 		StringProxy( CharacterVector& v, int index ) ;
+		StringProxy( const StringProxy& other ) ;
 		
 		/**
 		 * lhs use. Assign the value of the referred element to 
@@ -88,7 +91,7 @@
 		 * element this proxy refers to and convert it to a 
 		 * C string
 		 */
-		operator char*() const ;
+		operator const char*() const ;
 		
 		/**
 		 * Prints the element this proxy refers to to an 
@@ -96,11 +99,46 @@
 		 */
 		friend std::ostream& operator<<(std::ostream& os, const StringProxy& proxy);
 		
+		friend class iterator ;
 	private:
 		CharacterVector& parent; 
 		int index ;
+		inline void move( int n ){ index += n ;}
 	} ;
 
+	class iterator {
+	public:
+		typedef StringProxy& reference ;
+		typedef StringProxy* pointer ;
+		typedef int difference_type ;
+		typedef StringProxy value_type;
+		typedef std::random_access_iterator_tag iterator_category ;
+		
+		iterator( CharacterVector& object, int index );
+		
+		iterator& operator++(); // prefix
+		iterator& operator++(int); // postfix
+		
+		iterator& operator--(); // prefix
+		iterator& operator--(int); // postfix
+		                    
+		iterator operator+(difference_type n) const ;
+		iterator operator-(difference_type n) const ;
+		
+		iterator& operator+=(difference_type n) ;
+		iterator& operator-=(difference_type n) ;
+
+		reference operator*() ;
+		pointer operator->();
+		
+		bool operator==( const iterator& y) ;
+		bool operator!=( const iterator& y) ;
+		difference_type operator-(const iterator& y) ;
+		
+	private:
+		StringProxy proxy ;
+	};
+	
 	/**
 	 * Default constructor. Sets the underlying object to NULL
 	 */
@@ -203,6 +241,10 @@
 	 */
 	StringProxy operator()( const size_t& i, const size_t& j) throw(index_out_of_bounds,not_a_matrix) ;
 
+	inline iterator begin() { return iterator(*this, 0 ) ; }
+	
+	inline iterator end() { return iterator(*this,::Rf_length(m_sexp));}
+	
 	template <typename InputIterator>
 	void assign( InputIterator first, InputIterator last){
 		size_t size = std::distance( first, last ) ;
@@ -224,6 +266,9 @@
 
 typedef CharacterVector StringVector ;
 
+std::string operator+( const std::string& x, const CharacterVector::StringProxy& y ) ;
+
+
 } // namespace
 
 #endif



More information about the Rcpp-commits mailing list