[Rcpp-devel] [Rcpp-commits] r442 - in pkg: inst src src/Rcpp

Romain Francois romain.francois at dbmail.com
Sun Jan 24 19:24:41 CET 2010


Some comments on this commit.

Instead of manually doing copy and paste between IntegerVector, 
NumericVector, LogicalVector, ComplexVector and RawVector every time I 
change something in one of them (e.g. adding matrix indexing),  I now 
let C++ templates do the work. It is much more accurate than me.

This way we get matrix indexing for all simple vector types for free.

It is completely transparent to the user.

I'll do something similar later about the complicated vector 
(GenericVector, ExpressionVector, CharacterVector), since they share 
even more (all of them are basically arrays of SEXP)

On 01/24/2010 07:21 PM, noreply at r-forge.r-project.org wrote:
>
> Author: romain
> Date: 2010-01-24 19:21:05 +0100 (Sun, 24 Jan 2010)
> New Revision: 442
>
> Added:
>     pkg/src/Rcpp/SimpleVector.h
> Removed:
>     pkg/src/ComplexVector.cpp
>     pkg/src/IntegerVector.cpp
>     pkg/src/LogicalVector.cpp
>     pkg/src/NumericVector.cpp
>     pkg/src/RawVector.cpp
> Modified:
>     pkg/inst/ChangeLog
>     pkg/src/Rcpp.h
>     pkg/src/Rcpp/ComplexVector.h
>     pkg/src/Rcpp/IntegerVector.h
>     pkg/src/Rcpp/LogicalVector.h
>     pkg/src/Rcpp/NumericVector.h
>     pkg/src/Rcpp/RawVector.h
>     pkg/src/Rcpp/VectorBase.h
>     pkg/src/Rcpp/as.h
>     pkg/src/RcppCommon.h
>     pkg/src/VectorBase.cpp
> Log:
> reimplemented all simple vectors as a catch all template SimpleVector
>
> Modified: pkg/inst/ChangeLog
> ===================================================================
> --- pkg/inst/ChangeLog	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/inst/ChangeLog	2010-01-24 18:21:05 UTC (rev 442)
> @@ -1,8 +1,14 @@
>   2010-01-24  Romain Francois<francoisromain at free.fr>
>
> -	* src/NumericVector.cpp: first pass at matrix indexing using
> -	operator()(size_t, size_t)
> +	* src/SimpleVector.h : new template to replace simple vector
> +	classes. now NumericVector, IntegerVector, LogicalVector,
> +	ComplexVector and RawVector are all generated from the same
> +	template class. A first attempt at matrix indexing is added
> +	as part of this.
>
> +	* int/unitTests/runit.NumericVector.R: new unit tests about
> +	matrix indexing
> +	
>   	* src/Rcpp/VectorBase.h: added the exception not_a_matrix
>   	that is thrown when attempting to perform matrix indexing on
>   	a vector that is not a matrix.
>
> Deleted: pkg/src/ComplexVector.cpp
> ===================================================================
> --- pkg/src/ComplexVector.cpp	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/ComplexVector.cpp	2010-01-24 18:21:05 UTC (rev 442)
> @@ -1,46 +0,0 @@
> -// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
> -//
> -// ComplexVector.h: Rcpp R/C++ interface class library -- complex 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/ComplexVector.h>
> -
> -namespace Rcpp{
> -	
> -	ComplexVector::ComplexVector(SEXP x) throw(not_compatible) : VectorBase(), start(0) {
> -		switch( TYPEOF( x ) ){
> -			case CPLXSXP:
> -				setSEXP( x ) ;
> -				break ;
> -			case REALSXP:
> -			case LGLSXP:
> -			case RAWSXP:
> -			case INTSXP:
> -				setSEXP( Rf_coerceVector( x, CPLXSXP) ) ;
> -				break ;
> -			default:
> -				throw not_compatible( "cannot convert to complex vector" ) ;
> -		}
> -	}
> -	
> -	ComplexVector::ComplexVector(int size) : VectorBase(), start(0) {
> -		setSEXP( Rf_allocVector(CPLXSXP, size) ) ;
> -	}
> -
> -} // namespace
>
> Deleted: pkg/src/IntegerVector.cpp
> ===================================================================
> --- pkg/src/IntegerVector.cpp	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/IntegerVector.cpp	2010-01-24 18:21:05 UTC (rev 442)
> @@ -1,45 +0,0 @@
> -// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
> -//
> -// IntegerVector.h: Rcpp R/C++ interface class library -- integer 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/IntegerVector.h>
> -
> -namespace Rcpp{
> -	
> -	IntegerVector::IntegerVector(SEXP x) throw(not_compatible) : VectorBase(), start(0) {
> -		switch( TYPEOF( x ) ){
> -			case INTSXP:
> -				setSEXP( x ) ;
> -				break ;
> -			case REALSXP:
> -			case LGLSXP:
> -			case RAWSXP:
> -				setSEXP( Rf_coerceVector( x, INTSXP) ) ;
> -				break ;
> -			default:
> -				throw not_compatible( "cannot convert to intrger vector" ) ;
> -		}
> -	}
> -	
> -	IntegerVector::IntegerVector(int size) : VectorBase(), start(0) {
> -		setSEXP( Rf_allocVector(INTSXP, size) ) ;
> -	}
> -
> -} // namespace
>
> Deleted: pkg/src/LogicalVector.cpp
> ===================================================================
> --- pkg/src/LogicalVector.cpp	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/LogicalVector.cpp	2010-01-24 18:21:05 UTC (rev 442)
> @@ -1,45 +0,0 @@
> -// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
> -//
> -// LogicalVector.h: Rcpp R/C++ interface class library -- integer 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/LogicalVector.h>
> -
> -namespace Rcpp{
> -	
> -	LogicalVector::LogicalVector(SEXP x) throw(not_compatible) : VectorBase() {
> -		switch( TYPEOF( x ) ){
> -			case LGLSXP:
> -				setSEXP( x ) ;
> -				break ;
> -			case RAWSXP:
> -			case INTSXP:
> -			case REALSXP:
> -				setSEXP( Rf_coerceVector( x, LGLSXP) ) ;
> -				break ;
> -			default:
> -				throw not_compatible( "cannot convert to intrger vector" ) ;
> -		}
> -	}
> -	
> -	LogicalVector::LogicalVector(int size) : VectorBase() {
> -		setSEXP( Rf_allocVector(LGLSXP, size) ) ;
> -	}
> -
> -} // namespace
>
> Deleted: pkg/src/NumericVector.cpp
> ===================================================================
> --- pkg/src/NumericVector.cpp	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/NumericVector.cpp	2010-01-24 18:21:05 UTC (rev 442)
> @@ -1,59 +0,0 @@
> -// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
> -//
> -// NumericVector.h: Rcpp R/C++ interface class library -- integer 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/NumericVector.h>
> -
> -namespace Rcpp{
> -	
> -	NumericVector::NumericVector(SEXP x) throw(not_compatible) : VectorBase(), start(0) {
> -		switch( TYPEOF( x ) ){
> -			case REALSXP:
> -				setSEXP( x ) ;
> -				break ;
> -			case INTSXP:
> -			case LGLSXP:
> -			case RAWSXP:
> -				setSEXP( Rf_coerceVector( x, REALSXP) ) ;
> -				break ;
> -			default:
> -				throw not_compatible( "cannot convert to numeric vector" ) ;
> -		}
> -	}
> -	
> -	NumericVector::NumericVector(int size) : VectorBase(), start(0) {
> -		setSEXP( Rf_allocVector(REALSXP, size) ) ;
> -	}
> -
> -	double&  NumericVector::operator()( const size_t&  i) throw(index_out_of_bounds){
> -		if( i>= static_cast<size_t>(Rf_length(m_sexp)) ) throw index_out_of_bounds() ;
> -		return start[i] ;
> -	}
> -	
> -	double&  NumericVector::operator()( const size_t&  i, const size_t&  j) throw(not_a_matrix,index_out_of_bounds){
> -		if( !Rf_isMatrix(m_sexp) ) throw not_a_matrix() ;
> -		int *dim = INTEGER( Rf_getAttrib( m_sexp, R_DimSymbol ) ) ;
> -		size_t nrow = static_cast<size_t>(dim[0]) ;
> -		size_t ncol = static_cast<size_t>(dim[1]) ;
> -		if( i>= nrow || j>= ncol ) throw index_out_of_bounds() ;
> -		return start[ i + nrow*j ] ;
> -	}
> -	
> -} // namespace
>
> Deleted: pkg/src/RawVector.cpp
> ===================================================================
> --- pkg/src/RawVector.cpp	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/RawVector.cpp	2010-01-24 18:21:05 UTC (rev 442)
> @@ -1,45 +0,0 @@
> -// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
> -//
> -// RawVector.h: Rcpp R/C++ interface class library -- integer 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/RawVector.h>
> -
> -namespace Rcpp{
> -	
> -	RawVector::RawVector(SEXP x) throw(not_compatible) : VectorBase(), start(0) {
> -		switch( TYPEOF( x ) ){
> -			case RAWSXP:
> -				setSEXP( x ) ;
> -				break ;
> -			case INTSXP:
> -			case REALSXP:
> -			case LGLSXP:
> -				setSEXP( Rf_coerceVector( x, RAWSXP) ) ;
> -				break ;
> -			default:
> -				throw not_compatible( "cannot convert to intrger vector" ) ;
> -		}
> -	}
> -	
> -	RawVector::RawVector(int size) : VectorBase(), start(0) {
> -		setSEXP( Rf_allocVector(RAWSXP, size) ) ;
> -	}
> -
> -} // namespace
>
> Modified: pkg/src/Rcpp/ComplexVector.h
> ===================================================================
> --- pkg/src/Rcpp/ComplexVector.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp/ComplexVector.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -23,48 +23,12 @@
>   #define Rcpp_ComplexVector_h
>
>   #include<RcppCommon.h>
> -#include<Rcpp/RObject.h>
> -#include<Rcpp/VectorBase.h>
> +#include<Rcpp/SimpleVector.h>
>
> -#ifdef HAS_INIT_LISTS
> -#include<initializer_list>
> -#include<algorithm>
> -#endif
> -
>   namespace Rcpp{
>
> -class ComplexVector : public VectorBase {
> -public:
> +typedef SimpleVector<CPLXSXP,Rcomplex>  ComplexVector ;	
>
> -	ComplexVector(SEXP x) throw(not_compatible);
> -	ComplexVector(int size) ;
> -	
> -#ifdef HAS_INIT_LISTS	
> -	ComplexVector( std::initializer_list<Rcomplex>  list ) : VectorBase(){
> -		fill( list.begin(), list.end() ) ;
> -	};
> -#endif
> -	
> -	inline Rcomplex&  operator[]( int i ) const { return start[i] ; }
> -	inline Rcomplex* begin() const { return start ; }
> -	inline Rcomplex* end() const { return start + LENGTH(m_sexp) ; }
> -	
> -	typedef Rcomplex* iterator ;
> -
> -private:
> -	Rcomplex* start ;
> -	virtual void update(){ start = COMPLEX(m_sexp);}
> -	
> -	template<typename InputIterator>
> -	void fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance(first, last) ;
> -		SEXP x = PROTECT( Rf_allocVector( CPLXSXP, size ) ) ;
> -		std::copy( first, last, COMPLEX(x) ) ;
> -		setSEXP(x) ;
> -		UNPROTECT( 1 ); /* x */
> -	}
> -} ;
> -
>   } // namespace
>
>   #endif
>
> Modified: pkg/src/Rcpp/IntegerVector.h
> ===================================================================
> --- pkg/src/Rcpp/IntegerVector.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp/IntegerVector.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -23,65 +23,12 @@
>   #define Rcpp_IntegerVector_h
>
>   #include<RcppCommon.h>
> -#include<Rcpp/RObject.h>
> -#include<Rcpp/VectorBase.h>
> +#include<Rcpp/SimpleVector.h>
>
> -#ifdef HAS_INIT_LISTS
> -#include<initializer_list>
> -#include<algorithm>
> -#endif
> -
>   namespace Rcpp{
>
> -class IntegerVector : public VectorBase {
> -public:
> +typedef SimpleVector<INTSXP,int>  IntegerVector ;
>
> -	IntegerVector(SEXP x) throw(not_compatible);
> -	IntegerVector(int size) ;
> -	
> -#ifdef HAS_INIT_LISTS	
> -	IntegerVector( std::initializer_list<int>  list ): VectorBase(), start(0) {
> -		simple_fill( list.begin(), list.end() );
> -	}
> -	IntegerVector( std::initializer_list<double>  list ) :VectorBase(), start(0) {
> -		coerce_and_fill( list.begin(), list.end() );
> -	}
> -#endif
> -
> -	inline int&  operator[]( int i ) const{ return start[i] ; }
> -	inline int* begin() const { return start ; }
> -	inline int* end() const { return start + LENGTH(m_sexp) ; }
> -	
> -	typedef int* iterator ;
> -
> -private:
> -	int* start ;
> -	virtual void update(){ start = INTEGER(m_sexp) ;}
> -	
> -	// simple is when there is no need for coercion
> -	template<typename InputIterator>
> -	void simple_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last) ;
> -		SEXP x = PROTECT( Rf_allocVector( INTSXP, size ) );
> -		std::copy( first, last, INTEGER(x) ) ;
> -		setSEXP( x ) ;
> -		UNPROTECT(1) ;
> -	}
> -	
> -	// need to coerce to int
> -	template<typename InputIterator>
> -	void coerce_and_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last) ;
> -		SEXP x = PROTECT( Rf_allocVector( INTSXP, size ) );
> -		// FIXME: actually coerce
> -		// std::transform( first, last, INTEGER(x), coerce<int>  ) ;
> -		std::copy( first, last, INTEGER(x) ) ;
> -		setSEXP( x ) ;
> -		UNPROTECT(1) ;
> -	}
> -
> -} ;
> -
>   } // namespace
>
>   #endif
>
> Modified: pkg/src/Rcpp/LogicalVector.h
> ===================================================================
> --- pkg/src/Rcpp/LogicalVector.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp/LogicalVector.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -23,66 +23,36 @@
>   #define Rcpp_LogicalVector_h
>
>   #include<RcppCommon.h>
> -#include<Rcpp/RObject.h>
> -#include<Rcpp/VectorBase.h>
> +#include<Rcpp/SimpleVector.h>
> +#include<Rcpp/as.h>
>
> -#ifdef HAS_INIT_LISTS
> -#include<initializer_list>
> -#include<algorithm>
> -#endif
> -
>   namespace Rcpp{
>
> -class LogicalVector : public VectorBase {
> +typedef SimpleVector<LGLSXP,int>  LogicalVector_Base ;
> +
> +class LogicalVector : public LogicalVector_Base{
>   public:
> +	LogicalVector() : LogicalVector_Base(){} ;
> +	LogicalVector(SEXP x) : LogicalVector_Base(x){} ;
> +	LogicalVector(const size_t&  size) : LogicalVector_Base(size){};
>
> -	LogicalVector(SEXP x) throw(not_compatible);
> -	LogicalVector( int size) ;
> -
> -#ifdef HAS_INIT_LISTS	
> -	LogicalVector( std::initializer_list<Rboolean>  list ) : VectorBase(), start(0) {
> -		simple_fill( list.begin(), list.end() ) ;
> -	}
> -	LogicalVector( std::initializer_list<int>  list ) : VectorBase(), start(0) {
> -		coerce_and_fill( list.begin(), list.end() ) ;
> -	}
> -	LogicalVector( std::initializer_list<bool>  list ) : VectorBase(), start(0) {
> -		coerce_and_fill( list.begin(), list.end() ) ;
> -	}
> +#ifdef HAS_INIT_LISTS
> +	LogicalVector( std::initializer_list<int>  list) : LogicalVector_Base(list){};
> +	LogicalVector( std::initializer_list<bool>  list) : LogicalVector_Base(){
> +		bool_fill(list.begin(), list.end());
> +	} ;
>   #endif
> -
> -	typedef int* iterator ;
> -
> -	inline int&  operator[]( int i ) const { return start[i] ;}
> -	inline int* begin() const { return start ; }
> -	inline int* end() const { return start + LENGTH(m_sexp); }
> -
> -private:
> -	int* start ;
> -	virtual void update(){ start=LOGICAL(m_sexp); }
>   	
> -	// called when there is no need for coercion
> +private:
>   	template<typename InputIterator>
> -	void simple_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last ) ;
> -		SEXP x = PROTECT( Rf_allocVector( LGLSXP, size ) ) ;
> -		std::copy( first, last, LOGICAL(x) );
> -		setSEXP(x) ;
> -		UNPROTECT( 1 ); /* x */
> +	void bool_fill( InputIterator first, InputIterator last){
> +		size_t size = std::distance( first, last) ;
> +		SEXP x = PROTECT( Rf_allocVector( LGLSXP, size ) );
> +		std::transform( first, last, get_pointer<LGLSXP,int>(x), bool_to_Rboolean  ) ;
> +		setSEXP( x ) ;
> +		UNPROTECT(1) ;
>   	}
> -	
> -	template<typename InputIterator>
> -	void coerce_and_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last ) ;
> -		SEXP x = PROTECT( Rf_allocVector( LGLSXP, size ) ) ;
> -		// FIXME : actually coerce
> -		// std::transform( first, last, LOGICAL(x), coerce_to_logical ) ;
> -		std::copy( first, last, LOGICAL(x) );
> -		setSEXP(x) ;
> -		UNPROTECT( 1 ); /* x */
> -	}
> -	
> -	
> +
>   } ;
>
>   } // namespace
>
> Modified: pkg/src/Rcpp/NumericVector.h
> ===================================================================
> --- pkg/src/Rcpp/NumericVector.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp/NumericVector.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -23,87 +23,12 @@
>   #define Rcpp_NumericVector_h
>
>   #include<RcppCommon.h>
> -#include<Rcpp/RObject.h>
> -#include<Rcpp/VectorBase.h>
> +#include<Rcpp/SimpleVector.h>
>
> -#ifdef HAS_INIT_LISTS
> -#include<initializer_list>
> -#include<algorithm>
> -#endif
> -
>   namespace Rcpp{
>
> -class NumericVector : public VectorBase {
> -public:
> +typedef SimpleVector<REALSXP,double>  NumericVector ;
>
> -	NumericVector(SEXP x) throw(not_compatible);
> -	NumericVector( int size) ;
> -	
> -#ifdef HAS_INIT_LISTS	
> -	NumericVector( std::initializer_list<int>  list ) : VectorBase(), start(0){
> -		coerce_and_fill( list.begin(), list.end() ) ;
> -	};
> -	NumericVector( std::initializer_list<double>  list ) : VectorBase(), start(0){
> -		simple_fill( list.begin(), list.end() ) ;
> -	}
> -#endif
> -	/** Fast 1d 0-based indexing. no bounds checking are performed */
> -	inline double&  operator[]( const int&  i ) { return start[i] ; }
> -	
> -	/** Returns a pointer to the internal array */
> -	inline double* begin() const { return start ; }
> -	
> -	/** Returns a pointer to the element after the last element of the array */
> -	inline double* end() const   { return start + Rf_length(m_sexp);}
> -	
> -	/** convenience typedef */
> -	typedef double* iterator ;
> -
> -	/** secure 1d 0-based indexing.
> -	 * As opposed to operator[], this operator performs bounds checks
> -	 * to make sure that i is valid. There is however a price associated
> -	 * with the check
> -	 *
> -	 * @param i 0-based index. this indexes the object as a vector
> -	 * so if it is actually a matrix the order is column-major (as in R)
> -	 */
> -	double&  operator()( const size_t&  i ) throw(index_out_of_bounds) ;
> -	
> -	/**
> -	 * matrix indexing.
> -	 */
> -	double&  operator()( const size_t&i, const size_t&  j) throw(not_a_matrix,index_out_of_bounds);
> -	
> -private:
> -	double *start ;
> -	virtual void update(){ start = REAL(m_sexp);}
> -	
> -	// simple is when there is no need for coercion
> -	// called only when the input container contains doubles
> -	template<typename InputIterator>
> -	void simple_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last) ;
> -		SEXP x = PROTECT( Rf_allocVector( REALSXP, size ) );
> -		std::copy( first, last, REAL(x) ) ;
> -		setSEXP( x ) ;
> -		UNPROTECT(1) ;
> -	}
> -	
> -	// need to coerce to double
> -	template<typename InputIterator>
> -	void coerce_and_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last) ;
> -		SEXP x = PROTECT( Rf_allocVector( REALSXP, size ) );
> -		// FIXME: actually coerce
> -		// std::transform( first, last, REAL(x), coerce_to_double ) ;
> -		std::copy( first, last, REAL(x) ) ;
> -		setSEXP( x ) ;
> -		UNPROTECT(1) ;
> -	}
> -	
> -	
> -} ;
> -
>   } // namespace
>
>   #endif
>
> Modified: pkg/src/Rcpp/RawVector.h
> ===================================================================
> --- pkg/src/Rcpp/RawVector.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp/RawVector.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -23,66 +23,12 @@
>   #define Rcpp_RawVector_h
>
>   #include<RcppCommon.h>
> -#include<Rcpp/RObject.h>
> -#include<Rcpp/VectorBase.h>
> +#include<Rcpp/SimpleVector.h>
>
> -#ifdef HAS_INIT_LISTS
> -#include<initializer_list>
> -#include<algorithm>
> -#endif
> -
>   namespace Rcpp{
>
> -class RawVector : public VectorBase {
> -public:
> +typedef SimpleVector<RAWSXP,Rbyte>  RawVector ;
>
> -	RawVector(SEXP x) throw(not_compatible);
> -	RawVector( int size) ;
> -	
> -#ifdef HAS_INIT_LISTS	
> -	RawVector( std::initializer_list<Rbyte>  list ) : VectorBase(), start(0) {
> -		simple_fill( list.begin(), list.end() ) ;
> -	}
> -	RawVector( std::initializer_list<int>  list ) : VectorBase(), start(0) {
> -		coerce_and_fill( list.begin(), list.end() ) ;
> -	}
> -#endif
> -	
> -	inline Rbyte&  operator[]( int i ) const { return start[i] ; }
> -	inline Rbyte* begin() const { return start ; }
> -	inline Rbyte* end() const { return start + LENGTH(m_sexp) ; }
> -	
> -	typedef Rbyte* iterator ;
> -
> -private:
> -	Rbyte* start ;
> -	virtual void update(){ start=RAW(m_sexp); }
> -	
> -	// simple is when there is no need for coercion
> -	// called only when the input container contains raw bytes
> -	template<typename InputIterator>
> -	void simple_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last) ;
> -		SEXP x = PROTECT( Rf_allocVector( RAWSXP, size ) );
> -		std::copy( first, last, RAW(x) ) ;
> -		setSEXP( x ) ;
> -		UNPROTECT(1) ;
> -	}
> -	
> -	// need to coerce to raw bytes
> -	template<typename InputIterator>
> -	void coerce_and_fill( InputIterator first, InputIterator last){
> -		size_t size = std::distance( first, last) ;
> -		SEXP x = PROTECT( Rf_allocVector( RAWSXP, size ) );
> -		// FIXME: actually coerce
> -		// std::transform( first, last, RAW(x), coerce<RAWSXP>  ) ;
> -		std::copy( first, last, RAW(x) ) ;
> -		setSEXP( x ) ;
> -		UNPROTECT(1) ;
> -	}
> -	
> -} ;
> -
>   } // namespace
>
>   #endif
>
> Added: pkg/src/Rcpp/SimpleVector.h
> ===================================================================
> --- pkg/src/Rcpp/SimpleVector.h	                        (rev 0)
> +++ pkg/src/Rcpp/SimpleVector.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -0,0 +1,105 @@
> +// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
> +//
> +// SimpleVector.h: Rcpp R/C++ interface class library -- simple vectors (INTSXP,REALSXP,RAWSXP,LGLSXP,CPLXSXP)
> +//
> +// 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_SimpleVector_h
> +#define Rcpp_SimpleVector_h
> +
> +#include<RcppCommon.h>
> +#include<Rcpp/VectorBase.h>
> +
> +namespace Rcpp{
> +	
> +template<int RTYPE, typename CTYPE>
> +class SimpleVector : public VectorBase {
> +public:
> +	SimpleVector() : VectorBase(), start(0){}
> +	
> +	SimpleVector(SEXP x) throw(not_compatible) : VectorBase(), start(0) {
> +		int type = TYPEOF(x) ;
> +		switch( type ){
> +			case RTYPE:
> +				setSEXP( x) ;
> +				break ;
> +			default:
> +				if( type == INTSXP || type == LGLSXP || type == CPLXSXP || type == RAWSXP || type == REALSXP ){
> +					setSEXP( Rf_coerceVector(x, RTYPE ) );
> +					break ;
> +				} else{
> +					/* TODO : include RTYPE in the message  */
> +					throw not_compatible( "cannot convert to simple vector" ) ;
> +				}
> +		}
> +	}
> +
> +	SimpleVector( const size_t&  size): VectorBase(), start(0){
> +		setSEXP( Rf_allocVector( RTYPE, size ) ) ;
> +	}
> +	
> +#ifdef HAS_INIT_LISTS
> +	SimpleVector( std::initializer_list<CTYPE>  list ) : VectorBase(), start(0){
> +		simple_fill( list.begin() , list.end() ) ;
> +	}
> +#endif
> +
> +	inline CTYPE&  operator[]( const int&  i ){ return start[i] ; }
> +	inline CTYPE* begin() const{ return start ; }
> +	inline CTYPE* end() const{ return start+Rf_length(m_sexp); }
> +	
> +	CTYPE&  operator()( const size_t&  i) throw(index_out_of_bounds){
> +		if( i>= static_cast<size_t>(Rf_length(m_sexp)) ) throw index_out_of_bounds() ;
> +		return start[i] ;
> +	}
> +	
> +	CTYPE&  operator()( const size_t&  i, const size_t&  j) throw(not_a_matrix,index_out_of_bounds){
> +		/* TODO: factor this code out into a Offset class otr something */
> +		if( !Rf_isMatrix(m_sexp) ) throw not_a_matrix() ;
> +		int *dim = INTEGER( Rf_getAttrib( m_sexp, R_DimSymbol ) ) ;
> +		size_t nrow = static_cast<size_t>(dim[0]) ;
> +		size_t ncol = static_cast<size_t>(dim[1]) ;
> +		if( i>= nrow || j>= ncol ) throw index_out_of_bounds() ;
> +		return start[ i + nrow*j ] ;
> +	}
> +
> +protected:
> +	/* TODO: make this private ASAP */
> +	CTYPE* start ;
> +	
> +private:
> +	virtual void update(){ start = get_pointer<RTYPE,CTYPE>(m_sexp) ; }
> +	
> +	// simple is when there is no need for coercion
> +	// called only when the input container contains doubles
> +	// TODO: use traits or something to make sure this is an
> +	//       iterator over RTYPE
> +	template<typename InputIterator>
> +	void simple_fill( InputIterator first, InputIterator last){
> +		size_t size = std::distance( first, last) ;
> +		SEXP x = PROTECT( Rf_allocVector( RTYPE, size ) );
> +		std::copy( first, last, get_pointer<RTYPE,CTYPE>(x) ) ;
> +		setSEXP( x ) ;
> +		UNPROTECT(1) ;
> +	}
> +	
> +} ;
> +
> +}// namespace Rcpp
> +
> +#endif
>
> Modified: pkg/src/Rcpp/VectorBase.h
> ===================================================================
> --- pkg/src/Rcpp/VectorBase.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp/VectorBase.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -51,6 +51,13 @@
>   	
>   } ;
>
> +template<int sexptype, typename T>  T* get_pointer(SEXP x){ throw std::exception( "not implemented" ) ; return static_cast<T*>(0); }
> +template<>  double* get_pointer<REALSXP,double>(SEXP x) ;
> +template<>  int* get_pointer<INTSXP,int>(SEXP x) ;
> +template<>  int* get_pointer<LGLSXP,int>(SEXP x) ;
> +template<>  Rcomplex* get_pointer<CPLXSXP,Rcomplex>(SEXP x) ;
> +template<>  Rbyte* get_pointer<RAWSXP,Rbyte>(SEXP x) ;
> +
>   } // namespace
>
>   #endif
>
> Modified: pkg/src/Rcpp/as.h
> ===================================================================
> --- pkg/src/Rcpp/as.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp/as.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -52,6 +52,8 @@
>   inline bool Rbyte_to_bool(Rbyte x){ return x != static_cast<Rbyte>(0) ; }
>
>   /* these take care of coercion */
> +inline int bool_to_Rboolean(bool x){ return x ? TRUE : FALSE ; }
> +
>   inline int Rboolean_to_int(int x){ return (x==NA_LOGICAL) ? NA_INTEGER : x ; }
>   inline int double_to_int(double x){
>   	if (ISNAN(x)) return NA_INTEGER;
>
> Modified: pkg/src/Rcpp.h
> ===================================================================
> --- pkg/src/Rcpp.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/Rcpp.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -47,6 +47,8 @@
>   #include<Rcpp/wrap.h>
>   #include<Rcpp/as.h>
>   #include<Rcpp/RObject.h>
> +#include<Rcpp/VectorBase.h>
> +#include<Rcpp/SimpleVector.h>
>   #include<Rcpp/XPtr.h>
>   #include<Rcpp/Environment.h>
>   #include<Rcpp/Evaluator.h>
>
> Modified: pkg/src/RcppCommon.h
> ===================================================================
> --- pkg/src/RcppCommon.h	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/RcppCommon.h	2010-01-24 18:21:05 UTC (rev 442)
> @@ -45,6 +45,10 @@
>   #include<stdexcept>
>   #include<vector>
>
> +#ifdef HAS_INIT_LISTS
> +#include<initializer_list>
> +#endif
> +
>   // include R headers, but set R_NO_REMAP and access everything via Rf_ prefixes
>   #define R_NO_REMAP
>   #include<R.h>
> @@ -104,15 +108,10 @@
>   	class Named ;
>   	class Pairlist ;
>   	class Function ;
> -	class IntegerVector;
> -	class NumericVector;
> -	class RawVector;
> -	class LogicalVector;
>   	class GenericVector;
>   	class WeakReference;
>   	class CharacterVector;
>   	class ExpressionVector;
> -	class ComplexVector;
>   }
>
>
>
> Modified: pkg/src/VectorBase.cpp
> ===================================================================
> --- pkg/src/VectorBase.cpp	2010-01-24 12:00:31 UTC (rev 441)
> +++ pkg/src/VectorBase.cpp	2010-01-24 18:21:05 UTC (rev 442)
> @@ -27,4 +27,10 @@
>   	VectorBase::VectorBase(): RObject(){} ;
>   	VectorBase::~VectorBase(){}
>
> +	template<>  double* get_pointer<REALSXP,double>(SEXP x){ return REAL(x) ; }
> +	template<>  int* get_pointer<INTSXP,int>(SEXP x){ return INTEGER(x) ; }
> +	template<>  int* get_pointer<LGLSXP,int>(SEXP x){ return LOGICAL(x) ; }
> +	template<>  Rcomplex* get_pointer<CPLXSXP,Rcomplex>(SEXP x){ return COMPLEX(x) ; }
> +	template<>  Rbyte* get_pointer<RAWSXP,Rbyte>(SEXP x){ return RAW(x) ; }
> +
>   } // namespace
>
> _______________________________________________
> Rcpp-commits mailing list
> Rcpp-commits at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-commits
>
>


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/KfKn : Rcpp 0.7.2
|- http://tr.im/JOlc : External pointers with Rcpp
`- http://tr.im/JFqa : R Journal, Volume 1/2, December 2009



More information about the Rcpp-devel mailing list