[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