[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