[Rcpp-commits] r455 - in pkg: inst src src/Rcpp

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Jan 25 15:32:41 CET 2010


Author: romain
Date: 2010-01-25 15:32:40 +0100 (Mon, 25 Jan 2010)
New Revision: 455

Added:
   pkg/src/Rcpp/SEXP_Vector.h
   pkg/src/SEXP_Vector.cpp
Removed:
   pkg/src/GenericVector.cpp
Modified:
   pkg/inst/ChangeLog
   pkg/src/ExpressionVector.cpp
   pkg/src/Rcpp.h
   pkg/src/Rcpp/ExpressionVector.h
   pkg/src/Rcpp/GenericVector.h
   pkg/src/Rcpp/wrap.h
   pkg/src/RcppCommon.h
Log:
merge ExpressionVector and GenericVector into the SEXP_Vector template

Modified: pkg/inst/ChangeLog
===================================================================
--- pkg/inst/ChangeLog	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/inst/ChangeLog	2010-01-25 14:32:40 UTC (rev 455)
@@ -1,5 +1,17 @@
 2010-01-25  Romain Francois <francoisromain at free.fr>
 
+	* src/Rcpp/wrap.h: wrap is back at being a template. The 
+	template parameter T is first converted to SEXP implicitely 
+	and the wrap(SEXP) method is used. This allows clients to only have to 
+	implement an implicit conversion to SEXP operator for their class
+	and have wrap for free.
+
+	* src/Rcpp/SEXP_Vector.h: factored out ExpressionVector and 
+	GenericVector into a templated SEXP_Vector class parameterized
+	by the SEXP type (VECSXP or EXPRSXP). GenericVector and 
+	ExpressionVector now are generated from the template. This will
+	ease adding features to both classes.
+
 	* src/as.cpp: also use coercion for as<bool>, as<int>, as<double>
 	as<Rbyte> (FR #768)
 

Modified: pkg/src/ExpressionVector.cpp
===================================================================
--- pkg/src/ExpressionVector.cpp	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/src/ExpressionVector.cpp	2010-01-25 14:32:40 UTC (rev 455)
@@ -27,29 +27,10 @@
 	ExpressionVector::parse_error::~parse_error() throw(){}
 	const char* ExpressionVector::parse_error::what() const throw(){ return "parse error" ; }
 	
-	ExpressionVector::ExpressionVector(SEXP x) throw(not_compatible) : VectorBase() {
-		switch( TYPEOF( x ) ){
-			case EXPRSXP:
-				setSEXP( x ) ;
-				break ;
-			default:
-				{
-					SEXP res = R_NilValue ;
-					try{
-						res = Evaluator::run( Rf_lang2( Rf_install("as.expression"), x ) ) ;
-					} catch( const Evaluator::eval_error& e){
-						throw not_compatible( "could not convert to an expression vector" ) ;
-					}
-					setSEXP( res ) ;
-				}
-		}
-	}
+	ExpressionVector::ExpressionVector(SEXP x) throw(not_compatible) : ExpressionVector_Base(x) {}
+	ExpressionVector::ExpressionVector(const size_t& size) : ExpressionVector_Base(size) {}
 	
-	ExpressionVector::ExpressionVector(int size) : VectorBase() {
-		setSEXP( Rf_allocVector(EXPRSXP, size) ) ;
-	}
-
-	ExpressionVector::ExpressionVector(const std::string& code) throw(parse_error){
+	ExpressionVector::ExpressionVector(const std::string& code) throw(parse_error) : ExpressionVector_Base() {
 		ParseStatus status;
 		SEXP expr = PROTECT( Rf_mkString( code.c_str() ) );
 		SEXP res  = PROTECT( R_ParseVector(expr, -1, &status, R_NilValue));
@@ -64,33 +45,6 @@
 		}
 	}
 
-ExpressionVector::Proxy::Proxy(ExpressionVector& v, int i) :
-	parent(v), index(i){}
-
-ExpressionVector::Proxy::operator SEXP() const{
-	return VECTOR_ELT( parent, index ) ;
-}
-
-ExpressionVector::Proxy& ExpressionVector::Proxy::operator=( const Proxy& rhs){
-	SET_VECTOR_ELT( parent, index, VECTOR_ELT( rhs.parent, rhs.index) ) ;
-	return *this ;
-}
-
-ExpressionVector::Proxy& ExpressionVector::Proxy::operator=( SEXP rhs){
-	SET_VECTOR_ELT( parent, index, rhs ) ;
-	return *this ;
-}
-
-const ExpressionVector::Proxy ExpressionVector::operator[](int i) const throw(index_out_of_bounds){
-	if( i<0 || i>= length()) throw index_out_of_bounds() ;
-	return Proxy(const_cast<ExpressionVector&>(*this), i) ;
-}
-
-ExpressionVector::Proxy ExpressionVector::operator[](int i) throw(index_out_of_bounds){
-	if( i<0 || i>= length()) throw index_out_of_bounds() ;
-	return Proxy(*this, i ) ;
-}
-
 SEXP ExpressionVector::eval() throw(Evaluator::eval_error){
 	return Evaluator::run( Rf_lcons( Rf_install( "eval" ) , Rf_cons( m_sexp, R_NilValue) )) ;
 }

Deleted: pkg/src/GenericVector.cpp
===================================================================
--- pkg/src/GenericVector.cpp	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/src/GenericVector.cpp	2010-01-25 14:32:40 UTC (rev 455)
@@ -1,83 +0,0 @@
-// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
-//
-// GenericVector.cpp: Rcpp R/C++ interface class library -- generic vectors (lists)
-//
-// Copyright (C) 2010	Dirk Eddelbuettel and Romain Francois
-//
-// 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/>.
-
-#include <Rcpp/GenericVector.h>
-
-namespace Rcpp{
-	
-	GenericVector::GenericVector(SEXP x) throw(not_compatible) : VectorBase() {
-		switch( TYPEOF( x ) ){
-			case VECSXP:
-				setSEXP( x ) ;
-				break ;
-			default:
-				{
-					SEXP res = R_NilValue ; 
-					try{
-						res = Evaluator::run( Rf_lang2( Rf_install( "as.list" ), x ) ) ;
-					} catch( const Evaluator::eval_error& ex){
-						throw not_compatible( "could not convert to a list" ) ;
-					}
-					setSEXP( res ) ;
-				}
-		}
-	}
-	
-	GenericVector::GenericVector(int size) : VectorBase() {
-		setSEXP( Rf_allocVector(VECSXP, size) ) ;
-	}
-
-/* proxy stuff */
-
-GenericVector::Proxy::Proxy(GenericVector& v, int i) :
-	parent(v), index(i){}
-
-GenericVector::Proxy::operator SEXP() const{
-	return VECTOR_ELT( parent, index ) ;
-}
-
-GenericVector::Proxy& GenericVector::Proxy::operator=( const Proxy& rhs){
-	SET_VECTOR_ELT( parent, index, VECTOR_ELT( rhs.parent, rhs.index) ) ;
-	return *this ;
-}
-
-GenericVector::Proxy& GenericVector::Proxy::operator=( SEXP rhs){
-	SET_VECTOR_ELT( parent, index, rhs ) ;
-	return *this ;
-}
-
-GenericVector::Proxy& GenericVector::Proxy::operator=( const Environment::Binding& rhs){
-	SET_VECTOR_ELT( parent, index, rhs ) ;
-	return *this ;
-}
-
-const GenericVector::Proxy GenericVector::operator[](int i) const throw(index_out_of_bounds){
-	if( i<0 || i>=length()) throw index_out_of_bounds() ;
-	return Proxy(const_cast<GenericVector&>(*this), i) ;
-}
-
-GenericVector::Proxy GenericVector::operator[](int i) throw(index_out_of_bounds){
-	if( i<0 || i>=length()) throw index_out_of_bounds() ;
-	return Proxy(*this, i ) ;
-}
-
-
-} // namespace 

Modified: pkg/src/Rcpp/ExpressionVector.h
===================================================================
--- pkg/src/Rcpp/ExpressionVector.h	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/src/Rcpp/ExpressionVector.h	2010-01-25 14:32:40 UTC (rev 455)
@@ -23,16 +23,16 @@
 #define Rcpp_ExpressionVector_h
 
 #include <RcppCommon.h>
-#include <Rcpp/RObject.h>
-#include <Rcpp/VectorBase.h>
-#include <Rcpp/Evaluator.h>
-#include <Rcpp/Environment.h>
+#include <Rcpp/wrap.h>
+#include <Rcpp/SEXP_Vector.h>
 
 namespace Rcpp{ 
 
-class ExpressionVector : public VectorBase {     
-public:
+/* lazyness typedef */
+typedef SEXP_Vector<EXPRSXP> ExpressionVector_Base ;
 
+class ExpressionVector : public ExpressionVector_Base {     
+public:
 	class parse_error : public std::exception{
 	public:
 		parse_error() throw();
@@ -40,59 +40,13 @@
 	        virtual const char* what() const throw() ;
 	} ;
 	
-	/* much inspired from item 30 of more effective C++ */
-	class Proxy {
-	public:
-		Proxy( ExpressionVector& v, int index ) ;
-		
-		/* lvalue uses */
-		Proxy& operator=(const Proxy& rhs) ;
-		Proxy& operator=(SEXP rhs) ;
-
-		template <typename T>
-		Proxy& operator=( const T& rhs){
-			SET_VECTOR_ELT( parent, index, wrap(rhs) ) ;
-			return *this; 
-		}
-
-		/* rvalue use */
-		operator SEXP() const ;
-
-	private:
-		ExpressionVector& parent; 
-		int index ;
-	} ;
-
 	ExpressionVector(SEXP x) throw(not_compatible);
-	ExpressionVector(int size) ;
+	ExpressionVector(const size_t& size) ;
 	ExpressionVector(const std::string& code) throw(parse_error) ;
 	
 	SEXP eval() throw(Evaluator::eval_error) ;
 	SEXP eval(const Environment& env) throw(Evaluator::eval_error);
-	
-#ifdef HAS_INIT_LISTS	
-	ExpressionVector( std::initializer_list<SEXP> list ) : VectorBase(){
-		  fill( list.begin(), list.end() ) ;
-	}
-#endif
 
-	const Proxy operator[]( int i ) const throw(index_out_of_bounds);
-	Proxy operator[]( int i ) throw(index_out_of_bounds) ;
-
-	friend class Proxy; 
-
-private:
-	template <typename InputIterator>
-	void fill( InputIterator first, InputIterator last){
-		size_t size = std::distance( first, last );
-		SEXP x = PROTECT( Rf_allocVector( EXPRSXP, size ) ) ;
-		for( size_t i=0; i<size ; i++, ++first){
-			SET_VECTOR_ELT( x, i, *first ) ;
-		}
-		setSEXP( x ) ;
-		UNPROTECT( 1 ); /* x */
-	}
-
 } ;
 
 } // namespace

Modified: pkg/src/Rcpp/GenericVector.h
===================================================================
--- pkg/src/Rcpp/GenericVector.h	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/src/Rcpp/GenericVector.h	2010-01-25 14:32:40 UTC (rev 455)
@@ -24,69 +24,11 @@
 
 #include <RcppCommon.h>
 #include <Rcpp/wrap.h>
-#include <Rcpp/Environment.h>
-#include <Rcpp/RObject.h>
-#include <Rcpp/VectorBase.h>
-#include <Rcpp/Evaluator.h>
-#include <Rcpp/Symbol.h>
+#include <Rcpp/SEXP_Vector.h>
 
 namespace Rcpp{ 
 
-class GenericVector : public VectorBase {     
-public:
-
-	/* much inspired from item 30 of more effective C++ */
-	class Proxy {
-	public:
-		Proxy( GenericVector& v, int index ) ;
-		
-		/* lvalue uses */
-		Proxy& operator=(const Proxy& rhs) ;
-		Proxy& operator=(SEXP rhs) ;
-		
-		template <typename T>
-		Proxy& operator=( const T& rhs){
-			SET_VECTOR_ELT( parent, index, wrap(rhs) ) ;
-			return *this; 
-		}
-		Proxy& operator=( const Environment::Binding& rhs) ;
-		
-		/* rvalue use */
-		operator SEXP() const ;
-		
-	private:
-		GenericVector& parent; 
-		int index ;
-	} ;
-
-
-	GenericVector(SEXP x) throw(not_compatible);
-	GenericVector( int size) ;
-
-#ifdef HAS_INIT_LISTS
-	GenericVector( std::initializer_list<SEXP> list) : VectorBase(){
-		fill( list.begin(), list.end() ) ;
-	} ;
-#endif
-
-	const Proxy operator[]( int i ) const throw(index_out_of_bounds);
-	Proxy operator[]( int i ) throw(index_out_of_bounds) ;
-	
-	friend class Proxy; 
-
-	template <typename InputIterator>
-	void fill( InputIterator first, InputIterator last){
-		size_t size = std::distance( first, last );
-		SEXP x = PROTECT( Rf_allocVector( VECSXP, size ) ) ;
-		for( size_t i=0; i<size ; i++, ++first){
-			SET_VECTOR_ELT( x, i, *first ) ;
-		}
-		setSEXP( x ) ;
-		UNPROTECT( 1 ); /* x */
-	}
-	
-} ;
-
+typedef SEXP_Vector<VECSXP> GenericVector ;
 typedef GenericVector List ;
 
 #ifdef HAS_INIT_LISTS

Added: pkg/src/Rcpp/SEXP_Vector.h
===================================================================
--- pkg/src/Rcpp/SEXP_Vector.h	                        (rev 0)
+++ pkg/src/Rcpp/SEXP_Vector.h	2010-01-25 14:32:40 UTC (rev 455)
@@ -0,0 +1,132 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// SEXP_Vector.h: Rcpp R/C++ interface class library -- template for expression vector and generic vector
+//
+// Copyright (C) 2010	Dirk Eddelbuettel and Romain Francois
+//
+// 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_SEXP_Vector_h
+#define Rcpp_SEXP_Vector_h
+
+#include <RcppCommon.h>
+#include <Rcpp/VectorBase.h>
+#include <Rcpp/Environment.h>
+
+namespace Rcpp{
+	
+/* this is only meant for internal use (at least for now) */
+SEXP convert_using_rfunction(SEXP x, const char* fun) ;
+template <int RTYPE> SEXP converter(SEXP x) ;
+template<> SEXP converter<VECSXP>(SEXP x) ;
+template<> SEXP converter<EXPRSXP>(SEXP x) ;
+
+template <int RTYPE> class SEXP_Vector : public VectorBase{
+public:
+	
+	/* much inspired from item 30 of more effective C++ */
+	class Proxy {
+	public:
+		Proxy( SEXP_Vector<RTYPE>& v, size_t i ) : parent(v), index(i) {}
+		
+		/* lvalue uses */
+		Proxy& operator=(const Proxy& rhs){
+			SET_VECTOR_ELT( parent, index, VECTOR_ELT( rhs.parent, rhs.index) ) ;
+			return *this ;
+		}
+		
+		Proxy& operator=(SEXP rhs){
+			SET_VECTOR_ELT( parent, index, rhs ) ;
+			return *this ;
+		}
+		
+		template <typename T>
+		Proxy& operator=( const T& rhs){
+			SET_VECTOR_ELT( parent, index, wrap(rhs) ) ;
+			return *this; 
+		}
+		
+		/* rvalue use */
+		operator SEXP() {
+			return VECTOR_ELT( parent, index ) ; 
+		}
+		
+		template <typename U> operator U(){
+			SEXP xx = VECTOR_ELT( parent, index) ;
+			return as<U>( xx ) ;
+		}
+		
+		
+	private:
+		SEXP_Vector<RTYPE>& parent; 
+		size_t index ;
+	} ;
+
+	SEXP_Vector(): VectorBase(){}
+	
+	SEXP_Vector(SEXP x) : VectorBase() {
+		int type = TYPEOF(x) ;
+		if( type == RTYPE ){
+			setSEXP( x ) ;
+		} else {
+			SEXP y = converter<RTYPE>(x) ;
+			setSEXP( y );
+		}
+	}
+	
+	/* FIXME : this should be in VectorBase, which also should 
+	  templated by RTYPE */
+	SEXP_Vector(const size_t& size) : VectorBase(){
+		setSEXP( Rf_allocVector( RTYPE, size) ) ; 
+	}
+
+#ifdef HAS_INIT_LISTS
+	SEXP_Vector( std::initializer_list<SEXP> list) : VectorBase(){
+		fill_from_sexp_iterator( list.begin(), list.end() ) ;
+	} ;
+#endif
+	
+	const Proxy operator[]( int i ) const throw(index_out_of_bounds){
+		return Proxy(const_cast<SEXP_Vector<RTYPE>&>(*this), i) ;
+	}
+	Proxy operator[]( int i ) throw(index_out_of_bounds){
+		if( i<0 || i>=length()) throw index_out_of_bounds() ;
+		return Proxy(*this, i ) ; 
+	}
+
+	friend class Proxy; 
+	
+private:
+	
+	template <typename SEXP_Iterator>
+	void fill_from_sexp_iterator( SEXP_Iterator first, SEXP_Iterator last){
+		size_t size = std::distance( first, last );
+		SEXP x = PROTECT( Rf_allocVector( RTYPE, size ) ) ;
+		SEXP y = R_NilValue ; /* -Wall */
+		for( size_t i=0; i<size ; i++, ++first){
+			/* this is where the actual type of SEXP_Iterator matters */
+			y = *first ; 
+			SET_VECTOR_ELT( x, i, y ) ;
+		}
+		setSEXP( x ) ;
+		UNPROTECT( 1 ); /* x */
+	}
+
+} ;
+	
+} //namespace Rcpp
+
+#endif

Modified: pkg/src/Rcpp/wrap.h
===================================================================
--- pkg/src/Rcpp/wrap.h	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/src/Rcpp/wrap.h	2010-01-25 14:32:40 UTC (rev 455)
@@ -36,9 +36,13 @@
 namespace Rcpp{ 
 
 // factories
-
 RObject wrap(SEXP m_sexp) ;
 
+template <typename T> RObject wrap( const T& object){
+	SEXP x = object ; /* let implicit conversion work */
+	return wrap(x) ;  /* use the wrap(SEXP) function */
+}
+
 LogicalVector wrap(const bool & v); 
 NumericVector wrap(const double & v);
 IntegerVector wrap(const int & v);

Modified: pkg/src/Rcpp.h
===================================================================
--- pkg/src/Rcpp.h	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/src/Rcpp.h	2010-01-25 14:32:40 UTC (rev 455)
@@ -49,6 +49,7 @@
 #include <Rcpp/RObject.h>
 #include <Rcpp/VectorBase.h>
 #include <Rcpp/SimpleVector.h>
+#include <Rcpp/SEXP_Vector.h>
 #include <Rcpp/XPtr.h>
 #include <Rcpp/Environment.h>
 #include <Rcpp/Evaluator.h>

Modified: pkg/src/RcppCommon.h
===================================================================
--- pkg/src/RcppCommon.h	2010-01-25 13:08:24 UTC (rev 454)
+++ pkg/src/RcppCommon.h	2010-01-25 14:32:40 UTC (rev 455)
@@ -108,10 +108,8 @@
 	class Named ;
 	class Pairlist ;
 	class Function ;
-	class GenericVector; 
 	class WeakReference; 
 	class CharacterVector; 
-	class ExpressionVector; 
 } 
 
 

Added: pkg/src/SEXP_Vector.cpp
===================================================================
--- pkg/src/SEXP_Vector.cpp	                        (rev 0)
+++ pkg/src/SEXP_Vector.cpp	2010-01-25 14:32:40 UTC (rev 455)
@@ -0,0 +1,45 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// SEXP_Vector.cpp: Rcpp R/C++ interface class library -- template for expression and generic vectors
+//
+// Copyright (C) 2010	Dirk Eddelbuettel and Romain Francois
+//
+// 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/>.
+
+#include <Rcpp/SEXP_Vector.h>
+
+namespace Rcpp{
+	
+template<> SEXP converter<VECSXP>(SEXP x){
+	return convert_using_rfunction( x, "as.list" ) ;
+}
+template<> SEXP converter<EXPRSXP>(SEXP x){
+	return convert_using_rfunction( x, "as.expression" ) ;
+}
+
+SEXP convert_using_rfunction(SEXP x, const char* fun){
+	SEXP res = R_NilValue ; 
+	try{
+		res = Evaluator::run( Rf_lang2( Rf_install( fun ), x ) );
+	} catch( const Evaluator::eval_error& ex){
+		throw RObject::not_compatible( "not compatible" ) ;
+	}
+	return res ;
+}
+
+
+} // namespace Rcpp
+



More information about the Rcpp-commits mailing list