[Rcpp-commits] r784 - in pkg/Rcpp: inst src src/Rcpp
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Feb 24 13:58:04 CET 2010
Author: romain
Date: 2010-02-24 13:58:03 +0100 (Wed, 24 Feb 2010)
New Revision: 784
Removed:
pkg/Rcpp/src/VectorBase.cpp
Modified:
pkg/Rcpp/inst/ChangeLog
pkg/Rcpp/src/CharacterVector.cpp
pkg/Rcpp/src/RObject.cpp
pkg/Rcpp/src/Rcpp/CharacterVector.h
pkg/Rcpp/src/Rcpp/DottedPair.h
pkg/Rcpp/src/Rcpp/MatrixColumn.h
pkg/Rcpp/src/Rcpp/MatrixRow.h
pkg/Rcpp/src/Rcpp/RObject.h
pkg/Rcpp/src/Rcpp/SEXP_Vector.h
pkg/Rcpp/src/Rcpp/SimpleVector.h
pkg/Rcpp/src/Rcpp/VectorBase.h
pkg/Rcpp/src/Rcpp/exceptions.h
Log:
VectorBase becomes a template using the Curiously recurring template pattern
Modified: pkg/Rcpp/inst/ChangeLog
===================================================================
--- pkg/Rcpp/inst/ChangeLog 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/inst/ChangeLog 2010-02-24 12:58:03 UTC (rev 784)
@@ -1,5 +1,11 @@
2010-02-24 Romain Francois <romain at r-enthusiasts.com>
+ * src/Rcpp/exceptions.h: some exception classes factored out
+
+ * src/Rcpp/VectorBase.h: now a template, using the
+ Curiously recurring template pattern (the type parameter is
+ the derived class)
+
* src/Rcpp/SEXP_Vector.h: the intermediate class
SEXP_Vector_Base is removed, reverting the change on
2010-02-09. This will facilitate the introduction of the
Modified: pkg/Rcpp/src/CharacterVector.cpp
===================================================================
--- pkg/Rcpp/src/CharacterVector.cpp 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/CharacterVector.cpp 2010-02-24 12:58:03 UTC (rev 784)
@@ -24,9 +24,9 @@
namespace Rcpp{
-CharacterVector::CharacterVector() : VectorBase(){}
+CharacterVector::CharacterVector() : VectorBase<CharacterVector>(){}
-CharacterVector::CharacterVector(const CharacterVector& other) : VectorBase(){
+CharacterVector::CharacterVector(const CharacterVector& other) : VectorBase<CharacterVector>(){
setSEXP( other.asSexp() );
}
@@ -35,24 +35,24 @@
return *this ;
}
-CharacterVector::CharacterVector(SEXP x) throw(not_compatible) : VectorBase() {
+CharacterVector::CharacterVector(SEXP x) throw(not_compatible) : VectorBase<CharacterVector>() {
SEXP y = r_cast<STRSXP>( x) ;
setSEXP( y ) ;
}
-CharacterVector::CharacterVector(const size_t& size) : VectorBase(){
+CharacterVector::CharacterVector(const size_t& size) : VectorBase<CharacterVector>(){
setSEXP( Rf_allocVector( STRSXP, size ) ) ;
}
-CharacterVector::CharacterVector( const std::string& x) : VectorBase() {
+CharacterVector::CharacterVector( const std::string& x) : VectorBase<CharacterVector>() {
setSEXP( Rf_mkString(x.c_str()) ) ;
}
-CharacterVector::CharacterVector( const std::vector<std::string>& x): VectorBase() {
+CharacterVector::CharacterVector( const std::vector<std::string>& x): VectorBase<CharacterVector>() {
assign( x.begin(), x.end() ) ;
}
-CharacterVector::CharacterVector( const Dimension& dims): VectorBase(){
+CharacterVector::CharacterVector( const Dimension& dims): VectorBase<CharacterVector>(){
setSEXP( Rf_allocVector( STRSXP, dims.prod() ) ) ;
if( dims.size() > 1 ) attr( "dim" ) = dims ;
}
Modified: pkg/Rcpp/src/RObject.cpp
===================================================================
--- pkg/Rcpp/src/RObject.cpp 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/RObject.cpp 2010-02-24 12:58:03 UTC (rev 784)
@@ -157,9 +157,6 @@
const char* RObject::not_s4::what( ) const throw() {
return "not an S4 object" ;
}
-const char* RObject::index_out_of_bounds::what( ) const throw() {
- return "array or list out of bounds" ;
-}
} // namespace Rcpp
Modified: pkg/Rcpp/src/Rcpp/CharacterVector.h
===================================================================
--- pkg/Rcpp/src/Rcpp/CharacterVector.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/CharacterVector.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -35,7 +35,7 @@
/**
* Representation of character vectors (STRSXP)
*/
-class CharacterVector : public VectorBase {
+class CharacterVector : public VectorBase<CharacterVector> {
public:
class iterator ;
@@ -213,7 +213,7 @@
* over std::string
*/
template <typename InputIterator>
- CharacterVector( InputIterator first, InputIterator last): VectorBase() {
+ CharacterVector( InputIterator first, InputIterator last): VectorBase<CharacterVector>() {
assign( first, last ) ;
}
Modified: pkg/Rcpp/src/Rcpp/DottedPair.h
===================================================================
--- pkg/Rcpp/src/Rcpp/DottedPair.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/DottedPair.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -23,6 +23,7 @@
#define Rcpp_DottedPair_h
#include <RcppCommon.h>
+#include <Rcpp/exceptions.h>
#include <Rcpp/Symbol.h>
#include <Rcpp/grow.h>
Modified: pkg/Rcpp/src/Rcpp/MatrixColumn.h
===================================================================
--- pkg/Rcpp/src/Rcpp/MatrixColumn.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/MatrixColumn.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -38,7 +38,7 @@
MatrixColumn( VECTOR& object, int i ) : parent(object), index(i){
if( ! ::Rf_isMatrix(parent) ) throw not_a_matrix() ;
- if( i < 0 || i >= parent.ncol() ) throw RObject::index_out_of_bounds() ;
+ if( i < 0 || i >= parent.ncol() ) throw index_out_of_bounds() ;
}
MatrixColumn( const MatrixColumn& other ) : parent(other.parent), index(other.index){} ;
Modified: pkg/Rcpp/src/Rcpp/MatrixRow.h
===================================================================
--- pkg/Rcpp/src/Rcpp/MatrixRow.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/MatrixRow.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -83,7 +83,7 @@
MatrixRow( VECTOR& object, int i ) : parent(object), index(i){
if( ! ::Rf_isMatrix(parent) ) throw not_a_matrix() ;
- if( i < 0 || i >= parent.nrow() ) throw RObject::index_out_of_bounds() ;
+ if( i < 0 || i >= parent.nrow() ) throw index_out_of_bounds() ;
}
MatrixRow( const MatrixRow& other ) : parent(other.parent), index(other.index){} ;
Modified: pkg/Rcpp/src/Rcpp/RObject.h
===================================================================
--- pkg/Rcpp/src/Rcpp/RObject.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/RObject.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -61,13 +61,6 @@
virtual const char* what() const throw() ;
} ;
- class index_out_of_bounds: public std::exception{
- public:
- index_out_of_bounds() throw(){};
- virtual ~index_out_of_bounds() throw(){};
- virtual const char* what() const throw() ;
- } ;
-
/**
* default constructor. uses R_NilValue
*/
Modified: pkg/Rcpp/src/Rcpp/SEXP_Vector.h
===================================================================
--- pkg/Rcpp/src/Rcpp/SEXP_Vector.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/SEXP_Vector.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -33,12 +33,13 @@
namespace Rcpp{
template <int RTYPE>
-class SEXP_Vector : public VectorBase {
+class SEXP_Vector : public VectorBase< SEXP_Vector<RTYPE> > {
public:
class iterator ;
class NameProxy ;
class Proxy ;
+ typedef VectorBase< SEXP_Vector<RTYPE> > Base ;
class Proxy {
public:
@@ -156,7 +157,7 @@
try{
index = parent.offset(name) ;
// parent[ index ] = x ;
- } catch( const RObject::index_out_of_bounds& ex ){
+ } catch( const index_out_of_bounds& ex ){
parent.push_back( Named(name, x ) );
}
}
@@ -175,38 +176,38 @@
typedef Proxy reference ;
typedef Proxy value_type ;
- SEXP_Vector() : VectorBase(){} ;
+ SEXP_Vector() : Base(){} ;
- SEXP_Vector(const SEXP_Vector& other) : VectorBase(){
- setSEXP( other.asSexp() ) ;
+ SEXP_Vector(const SEXP_Vector& other) : Base(){
+ Base::setSEXP( other.asSexp() ) ;
} ;
SEXP_Vector& operator=(const SEXP_Vector& other){
- setSEXP( other.asSexp() ) ;
+ Base::setSEXP( other.asSexp() ) ;
return *this ;
}
- SEXP_Vector(SEXP x) : VectorBase() {
+ SEXP_Vector(SEXP x) : Base() {
SEXP y = r_cast<RTYPE>(x) ;
- setSEXP( y );
+ Base::setSEXP( y );
}
- SEXP_Vector(const size_t& size) : VectorBase(){
- setSEXP( Rf_allocVector( RTYPE, size ) ) ;
+ SEXP_Vector(const size_t& size) : Base(){
+ Base::setSEXP( ::Rf_allocVector( RTYPE, size ) ) ;
}
- SEXP_Vector(const Dimension& dims) : VectorBase(){
- setSEXP( Rf_allocVector( RTYPE, dims.prod() ) ) ;
- if( dims.size() > 1) attr( "dim" ) = dims ;
+ SEXP_Vector(const Dimension& dims) : Base(){
+ Base::setSEXP( ::Rf_allocVector( RTYPE, dims.prod() ) ) ;
+ if( dims.size() > 1) Base::attr( "dim" ) = dims ;
}
template <typename InputIterator>
- SEXP_Vector(InputIterator first, InputIterator last) : VectorBase() {
+ SEXP_Vector(InputIterator first, InputIterator last) : Base() {
assign( first, last ) ;
}
#ifdef HAS_INIT_LISTS
- SEXP_Vector( std::initializer_list<SEXP> list) : VectorBase(){
+ SEXP_Vector( std::initializer_list<SEXP> list) : Base(){
assign( list.begin(), list.end() ) ;
} ;
#endif
@@ -219,27 +220,27 @@
}
inline const Proxy operator[]( int i ) const throw(index_out_of_bounds){
- return Proxy(const_cast<SEXP_Vector&>(*this), offset(i)) ;
+ return Proxy(const_cast<SEXP_Vector&>(*this), Base::offset(i)) ;
}
inline Proxy operator[]( int i ) throw(index_out_of_bounds){
- return Proxy(*this, offset(i) ) ;
+ return Proxy(*this, Base::offset(i) ) ;
}
inline iterator begin() { return iterator(*this, 0) ; }
- inline iterator end() { return iterator(*this, size() ) ; }
+ inline iterator end() { return iterator(*this, Base::size() ) ; }
Proxy operator()( const size_t& i) throw(index_out_of_bounds) {
- return Proxy(*this, offset(i) ) ;
+ return Proxy(*this, Base::offset(i) ) ;
}
Proxy operator()( const size_t& i, const size_t& j) throw(index_out_of_bounds,not_a_matrix){
- return Proxy(*this, offset(i,j) ) ;
+ return Proxy(*this, Base::offset(i,j) ) ;
}
template <typename InputIterator>
void assign( InputIterator first, InputIterator last){
/* FIXME: we might not need the wrap if the object already
has the appropriate length */
- setSEXP( r_cast<RTYPE>( wrap( first, last) ) ) ;
+ Base::setSEXP( r_cast<RTYPE>( wrap( first, last) ) ) ;
}
template <typename WRAPPABLE>
@@ -310,15 +311,15 @@
not sure what to do
*/
void push_back_sexp( SEXP t, bool named, const std::string& name ){
- if( isNULL() ){
+ if( Base::isNULL() ){
set_single( t, named, name );
} else {
- push_middle_sexp( size(), t, named, name ) ;
+ push_middle_sexp( Base::size(), t, named, name ) ;
}
}
void push_front_sexp( SEXP t, bool named, const std::string& name ){
- if( isNULL() ){
+ if( Base::isNULL() ){
set_single( t, named, name );
} else {
push_middle_sexp( 0, t, named, name ) ;
@@ -326,19 +327,19 @@
}
void erase_single( int index ){
- if( index >= size() || index < 0 ) throw RObject::index_out_of_bounds() ;
+ if( index >= Base::size() || index < 0 ) throw index_out_of_bounds() ;
- R_len_t n = size() ;
+ R_len_t n = Base::size() ;
SEXP x = PROTECT( Rf_allocVector( RTYPE, n-1 ) ) ;
R_len_t i=0 ;
for( ; i<index; i++){
- SET_VECTOR_ELT( x, i, VECTOR_ELT(m_sexp, i ) ) ;
+ SET_VECTOR_ELT( x, i, VECTOR_ELT(Base::m_sexp, i ) ) ;
}
i++; /* skip the one we don't want */
for( ; i<n; i++){
- SET_VECTOR_ELT( x, i-1, VECTOR_ELT(m_sexp, i ) ) ;
+ SET_VECTOR_ELT( x, i-1, VECTOR_ELT(Base::m_sexp, i ) ) ;
}
- SEXP names = RCPP_GET_NAMES( m_sexp ) ;
+ SEXP names = RCPP_GET_NAMES( Base::m_sexp ) ;
if( names != R_NilValue ){
SEXP x_names = PROTECT( Rf_allocVector( STRSXP, n-1) );
for( i=0; i<index; i++){
@@ -351,25 +352,25 @@
Rf_setAttrib( x, Rf_install("names"), x_names );
UNPROTECT(1) ; /* x_names */
}
- setSEXP( x );
+ Base::setSEXP( x );
UNPROTECT(1) ; /* x */
}
void erase_range( int first, int last ){
if( first > last ) throw std::range_error("invalid range") ;
- if( last >= size() || first < 0 ) throw RObject::index_out_of_bounds() ;
+ if( last >= Base::size() || first < 0 ) throw index_out_of_bounds() ;
int range_size = last - first + 1 ;
- R_len_t n = size() ;
+ R_len_t n = Base::size() ;
SEXP x = PROTECT( Rf_allocVector( RTYPE, n - range_size ) ) ;
R_len_t i=0 ;
for( ; i<first; i++){
- SET_VECTOR_ELT( x, i, VECTOR_ELT(m_sexp, i ) ) ;
+ SET_VECTOR_ELT( x, i, VECTOR_ELT(Base::m_sexp, i ) ) ;
}
for( i=last+1; i<n; i++){
- SET_VECTOR_ELT( x, i-range_size, VECTOR_ELT(m_sexp, i ) ) ;
+ SET_VECTOR_ELT( x, i-range_size, VECTOR_ELT(Base::m_sexp, i ) ) ;
}
- SEXP names = RCPP_GET_NAMES( m_sexp ) ;
+ SEXP names = RCPP_GET_NAMES( Base::m_sexp ) ;
if( names != R_NilValue ){
SEXP x_names = PROTECT( Rf_allocVector( STRSXP, n-range_size) );
for( i=0; i<first; i++){
@@ -381,26 +382,26 @@
Rf_setAttrib( x, Rf_install("names"), x_names );
UNPROTECT(1) ; /* x_names */
}
- setSEXP( x );
+ Base::setSEXP( x );
UNPROTECT(1) ; /* x */
}
void push_middle_sexp( int index, SEXP t, bool named, const std::string& name ){
- if( index > size() || index < 0 ) throw RObject::index_out_of_bounds() ;
+ if( index > Base::size() || index < 0 ) throw index_out_of_bounds() ;
PROTECT(t) ; /* just in case */
- R_len_t n = size() ;
+ R_len_t n = Base::size() ;
SEXP x = PROTECT( Rf_allocVector( RTYPE, n+1 ) ) ;
R_len_t i=0 ;
for( ; i<index; i++){
- SET_VECTOR_ELT( x, i, VECTOR_ELT(m_sexp, i ) ) ;
+ SET_VECTOR_ELT( x, i, VECTOR_ELT(Base::m_sexp, i ) ) ;
}
SET_VECTOR_ELT( x, i, t ) ;
for( ; i<n; i++){
- SET_VECTOR_ELT( x, i+1, VECTOR_ELT(m_sexp, i ) ) ;
+ SET_VECTOR_ELT( x, i+1, VECTOR_ELT(Base::m_sexp, i ) ) ;
}
- SEXP names = RCPP_GET_NAMES( m_sexp ) ;
+ SEXP names = RCPP_GET_NAMES( Base::m_sexp ) ;
if( names != R_NilValue ){
SEXP x_names = PROTECT( Rf_allocVector( STRSXP, n+1) );
for( i=0; i<index; i++){
@@ -418,7 +419,7 @@
Rf_setAttrib( x, Rf_install("names"), x_names );
UNPROTECT(1) ; /* x_names */
}
- setSEXP( x );
+ Base::setSEXP( x );
UNPROTECT(2) ; /* t, x */
}
@@ -431,7 +432,7 @@
Rf_setAttrib( x, Rf_install("names"), names) ;
UNPROTECT(1) ; /* names */
}
- setSEXP( x ) ;
+ Base::setSEXP( x ) ;
UNPROTECT(1) ;
}
Modified: pkg/Rcpp/src/Rcpp/SimpleVector.h
===================================================================
--- pkg/Rcpp/src/Rcpp/SimpleVector.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/SimpleVector.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -32,41 +32,42 @@
namespace Rcpp{
template <int RTYPE>
-class SimpleVector : public VectorBase {
+class SimpleVector : public VectorBase< SimpleVector<RTYPE> > {
public:
+ typedef VectorBase< SimpleVector<RTYPE> > Base ;
typedef typename traits::storage_type<RTYPE>::type value_type ;
typedef value_type* iterator ;
typedef value_type& reference ;
typedef MatrixRow<SimpleVector> Row ;
typedef MatrixColumn<SimpleVector> Column ;
- SimpleVector() : VectorBase(), start(0){}
+ SimpleVector() : Base(), start(0){}
- SimpleVector(SEXP x) throw(RObject::not_compatible) : VectorBase(), start(0){
+ SimpleVector(SEXP x) throw(RObject::not_compatible) : Base(), start(0){
SEXP y = r_cast<RTYPE>( x ) ;
- setSEXP( y );
+ Base::setSEXP( y );
}
- SimpleVector( const size_t& size){
- setSEXP( Rf_allocVector( RTYPE, size) ) ;
+ SimpleVector( const size_t& size) :Base() {
+ Base::setSEXP( Rf_allocVector( RTYPE, size) ) ;
init() ;
}
- SimpleVector( const Dimension& dims){
- setSEXP( Rf_allocVector( RTYPE, dims.prod() ) ) ;
+ SimpleVector( const Dimension& dims) : Base() {
+ Base::setSEXP( Rf_allocVector( RTYPE, dims.prod() ) ) ;
init() ;
if( dims.size() > 1 ){
- attr( "dim" ) = dims ;
+ Base::attr( "dim" ) = dims ;
}
}
- SimpleVector( const SimpleVector& other) : VectorBase() {
- setSEXP( other.asSexp() ) ;
+ SimpleVector( const SimpleVector& other) : Base() {
+ Base::setSEXP( other.asSexp() ) ;
}
SimpleVector& operator=(const SimpleVector& other){
- setSEXP( other.asSexp() ) ;
+ Base::setSEXP( other.asSexp() ) ;
return *this ;
}
@@ -76,31 +77,31 @@
}
template <typename InputIterator>
- SimpleVector( InputIterator first, InputIterator last) : VectorBase(), start(){
+ SimpleVector( InputIterator first, InputIterator last) : Base(), start(){
assign( first, last ) ;
}
#ifdef HAS_INIT_LISTS
- SimpleVector( std::initializer_list<value_type> list ) : VectorBase(), start(0){
+ SimpleVector( std::initializer_list<value_type> list ) : Base(), start(0){
assign( list.begin() , list.end() ) ;
}
#endif
inline reference operator[]( const int& i ){ return start[i] ; }
inline reference operator[]( const std::string& name) {
- return start[ offset(name) ];
+ return start[ Base::offset(name) ];
}
inline iterator begin() const{ return start ; }
- inline iterator end() const{ return start+Rf_length(m_sexp); }
+ inline iterator end() const{ return start+Rf_length(Base::m_sexp); }
- inline reference operator()( const size_t& i) throw(RObject::index_out_of_bounds){
- return start[ offset(i) ] ;
+ inline reference operator()( const size_t& i) throw(index_out_of_bounds){
+ return start[ Base::offset(i) ] ;
}
inline reference operator()( const std::string& name) {
- return start[ offset(name) ];
+ return start[ Base::offset(name) ];
}
- inline reference operator()( const size_t& i, const size_t& j) throw(not_a_matrix,RObject::index_out_of_bounds){
- return start[ offset(i,j) ] ;
+ inline reference operator()( const size_t& i, const size_t& j) throw(not_a_matrix,index_out_of_bounds){
+ return start[ Base::offset(i,j) ] ;
}
template <typename InputIterator>
@@ -109,7 +110,7 @@
allocating an unnecessary temporary object
*/
SEXP x = PROTECT( r_cast<RTYPE>( wrap( first, last ) ) );
- setSEXP( x) ;
+ Base::setSEXP( x) ;
UNPROTECT(1) ;
}
@@ -118,11 +119,11 @@
protected:
void init(){
- internal::r_init_vector<RTYPE>(m_sexp) ;
+ internal::r_init_vector<RTYPE>(Base::m_sexp) ;
}
void update_vector(){
- start = internal::r_vector_start<RTYPE,value_type>(m_sexp) ;
+ start = internal::r_vector_start<RTYPE,value_type>(Base::m_sexp) ;
}
private:
Modified: pkg/Rcpp/src/Rcpp/VectorBase.h
===================================================================
--- pkg/Rcpp/src/Rcpp/VectorBase.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/VectorBase.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -29,51 +29,77 @@
namespace Rcpp{
+template <typename VECTOR>
class VectorBase : public RObject {
public:
- VectorBase() ;
- virtual ~VectorBase() ;
-
+ VectorBase() : RObject(){} ;
+ virtual ~VectorBase(){};
+
/**
* the length of the vector, uses Rf_length
*/
inline R_len_t length() const { return ::Rf_length( m_sexp ) ; }
-
+
/**
* alias of length
*/
inline R_len_t size() const { return ::Rf_length( m_sexp ) ; }
-
- inline int ncol(){
- return dims()[1];
- }
+
+ inline int ncol(){
+ return dims()[1];
+ }
+
+ inline int nrow(){
+ return dims()[0];
+ }
- inline int nrow(){
- return dims()[0];
- }
-
/**
* offset based on the dimensions of this vector
*/
- size_t offset(const size_t& i, const size_t& j) const throw(not_a_matrix,RObject::index_out_of_bounds) ;
+ size_t offset(const size_t& i, const size_t& j) const throw(not_a_matrix,index_out_of_bounds){
+ if( !Rf_isMatrix(m_sexp) ) throw not_a_matrix() ;
+ /* we need to extract the dimensions */
+ 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 i + nrow*j ;
+ }
/**
* one dimensional offset doing bounds checking to ensure
* it is valid
*/
- size_t offset(const size_t& i) const throw(RObject::index_out_of_bounds);
+ size_t offset(const size_t& i) const throw(index_out_of_bounds){
+ if( static_cast<R_len_t>(i) >= Rf_length(m_sexp) ) throw index_out_of_bounds() ;
+ return i ;
+ }
- R_len_t offset(const std::string& name) const throw(RObject::index_out_of_bounds) ;
+ R_len_t offset(const std::string& name) const throw(index_out_of_bounds){
+ SEXP names = RCPP_GET_NAMES( m_sexp ) ;
+ if( names == R_NilValue ) throw index_out_of_bounds();
+ R_len_t n=size() ;
+ for( R_len_t i=0; i<n; ++i){
+ if( ! name.compare( CHAR(STRING_ELT(names, i)) ) ){
+ return i ;
+ }
+ }
+ throw index_out_of_bounds() ;
+ return -1 ; /* -Wall */
+ }
/* TODO: 3 dimensions, ... n dimensions through variadic templates */
class NamesProxy {
public:
- NamesProxy( const VectorBase& v) ;
+ NamesProxy( const VectorBase& v) : parent(v){} ;
/* lvalue uses */
- NamesProxy& operator=(const NamesProxy& rhs) ;
+ NamesProxy& operator=(const NamesProxy& rhs) {
+ set( rhs.get() ) ;
+ return *this ;
+ }
template <typename T>
NamesProxy& operator=(const T& rhs){
@@ -88,11 +114,29 @@
private:
const VectorBase& parent;
- SEXP get() const ;
- void set(SEXP x) const;
+ SEXP get() const {
+ return RCPP_GET_NAMES(parent) ;
+ }
+
+ void set(SEXP x) const {
+ SEXP new_vec = PROTECT( internal::try_catch(
+ Rf_lcons( Rf_install("names<-"),
+ Rf_cons( parent, Rf_cons( x , R_NilValue) )))) ;
+ /* names<- makes a new vector, so we have to change
+ the SEXP of the parent of this proxy, it might be
+ worth to work directly with the names attribute instead
+ of using the names<- R function, but then we need to
+ take care of coercion, recycling, etc ... we cannot just
+ brutally assign the names attribute */
+ const_cast<VectorBase&>(parent).setSEXP( new_vec ) ;
+ UNPROTECT(1) ; /* new_vec */
+ }
+
} ;
- NamesProxy names() const ;
+ NamesProxy names() const {
+ return NamesProxy(*this) ;
+ }
private:
Modified: pkg/Rcpp/src/Rcpp/exceptions.h
===================================================================
--- pkg/Rcpp/src/Rcpp/exceptions.h 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/Rcpp/exceptions.h 2010-02-24 12:58:03 UTC (rev 784)
@@ -30,7 +30,15 @@
virtual ~not_a_matrix() throw() {} ;
virtual const char* what() const throw() { return "not a matrix" ; };
} ;
-
+
+class index_out_of_bounds: public std::exception{
+ public:
+ index_out_of_bounds() throw(){};
+ virtual ~index_out_of_bounds() throw(){};
+ virtual const char* what() const throw(){ return "index out of bounds" ; } ;
+ } ;
+
+
} // namesapce Rcpp
#endif
Deleted: pkg/Rcpp/src/VectorBase.cpp
===================================================================
--- pkg/Rcpp/src/VectorBase.cpp 2010-02-24 12:24:30 UTC (rev 783)
+++ pkg/Rcpp/src/VectorBase.cpp 2010-02-24 12:58:03 UTC (rev 784)
@@ -1,88 +0,0 @@
-// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
-//
-// VectorBase.h: Rcpp R/C++ interface class library -- base vector class
-//
-// 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 <RcppCommon.h>
-#include <Rcpp/exceptions.h>
-#include <Rcpp/VectorBase.h>
-#include <Rcpp/CharacterVector.h>
-
-namespace Rcpp{
-
- VectorBase::VectorBase() : RObject() {} ;
- VectorBase::~VectorBase(){}
-
- size_t VectorBase::offset( const size_t& i, const size_t& j) const throw(not_a_matrix,RObject::index_out_of_bounds) {
- if( !Rf_isMatrix(m_sexp) ) throw not_a_matrix() ;
- /* we need to extract the dimensions */
- 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 RObject::index_out_of_bounds() ;
- return i + nrow*j ;
- }
-
- size_t VectorBase::offset(const size_t& i) const throw(RObject::index_out_of_bounds){
- if( static_cast<R_len_t>(i) >= Rf_length(m_sexp) ) throw RObject::index_out_of_bounds() ;
- return i ;
- }
-
- R_len_t VectorBase::offset(const std::string& name) const throw(RObject::index_out_of_bounds){
- SEXP names = RCPP_GET_NAMES( m_sexp ) ;
- if( names == R_NilValue ) throw RObject::index_out_of_bounds();
- R_len_t n=size() ;
- for( R_len_t i=0; i<n; ++i){
- if( ! name.compare( CHAR(STRING_ELT(names, i)) ) ){
- return i ;
- }
- }
- throw RObject::index_out_of_bounds() ;
- return -1 ; /* -Wall */
- }
-
-
- VectorBase::NamesProxy::NamesProxy( const VectorBase& v) : parent(v){} ;
- VectorBase::NamesProxy& VectorBase::NamesProxy::operator=( const NamesProxy& rhs){
- set( rhs.get() ) ;
- return *this ;
- }
-
- SEXP VectorBase::NamesProxy::get() const {
- return RCPP_GET_NAMES(parent) ;
- }
- void VectorBase::NamesProxy::set(SEXP x) const {
- SEXP new_vec = PROTECT( internal::try_catch(
- Rf_lcons( Rf_install("names<-"),
- Rf_cons( parent, Rf_cons( x , R_NilValue) )))) ;
- /* names<- makes a new vector, so we have to change
- the SEXP of the parent of this proxy, it might be
- worth to work directly with the names attribute instead
- of using the names<- R function, but then we need to
- take care of coercion, recycling, etc ... we cannot just
- brutally assign the names attribute */
- const_cast<VectorBase&>(parent).setSEXP( new_vec ) ;
- UNPROTECT(1) ; /* new_vec */
- }
-
- VectorBase::NamesProxy VectorBase::names() const{
- return NamesProxy(*this) ;
- }
-
-} // namespace )
More information about the Rcpp-commits
mailing list