From 14c88c5f502bbfb31ed17bccd3c09cb0bae5b194 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 11:40:55 -0700 Subject: [PATCH 01/11] hold nested sugar expressions and views by value Sugar nodes held every operand by const reference, so an expression kept past the full-expression that built it (e.g. in an auto variable) referred to destroyed temporaries. Nodes now hold nested expressions and views by value, and only objects that own an R object (vectors, matrices) by reference. Part of #1512. --- inst/include/Rcpp/stats/dpq/dpq.h | 48 ++++---- inst/include/Rcpp/sugar/block/SugarBlock_1.h | 4 +- inst/include/Rcpp/sugar/block/SugarBlock_2.h | 14 +-- inst/include/Rcpp/sugar/block/SugarBlock_3.h | 8 +- inst/include/Rcpp/sugar/block/SugarMath.h | 12 +- .../Rcpp/sugar/block/Vectorized_Math.h | 6 +- inst/include/Rcpp/sugar/functions/all.h | 8 +- inst/include/Rcpp/sugar/functions/any.h | 8 +- inst/include/Rcpp/sugar/functions/clamp.h | 2 +- inst/include/Rcpp/sugar/functions/complex.h | 4 +- inst/include/Rcpp/sugar/functions/cummax.h | 4 +- inst/include/Rcpp/sugar/functions/cummin.h | 4 +- inst/include/Rcpp/sugar/functions/cumprod.h | 4 +- inst/include/Rcpp/sugar/functions/cumsum.h | 4 +- inst/include/Rcpp/sugar/functions/diff.h | 12 +- inst/include/Rcpp/sugar/functions/head.h | 4 +- inst/include/Rcpp/sugar/functions/ifelse.h | 48 ++++---- inst/include/Rcpp/sugar/functions/is_finite.h | 2 +- .../Rcpp/sugar/functions/is_infinite.h | 2 +- inst/include/Rcpp/sugar/functions/is_na.h | 8 +- inst/include/Rcpp/sugar/functions/is_nan.h | 2 +- inst/include/Rcpp/sugar/functions/lapply.h | 4 +- .../Rcpp/sugar/functions/mapply/mapply_2.h | 8 +- .../Rcpp/sugar/functions/mapply/mapply_3.h | 6 +- inst/include/Rcpp/sugar/functions/max.h | 4 +- inst/include/Rcpp/sugar/functions/mean.h | 16 +-- inst/include/Rcpp/sugar/functions/min.h | 4 +- inst/include/Rcpp/sugar/functions/pmax.h | 6 +- inst/include/Rcpp/sugar/functions/pmin.h | 6 +- inst/include/Rcpp/sugar/functions/pow.h | 6 +- inst/include/Rcpp/sugar/functions/range.h | 4 +- inst/include/Rcpp/sugar/functions/rep.h | 6 +- inst/include/Rcpp/sugar/functions/rep_each.h | 4 +- inst/include/Rcpp/sugar/functions/rep_len.h | 4 +- inst/include/Rcpp/sugar/functions/rev.h | 4 +- inst/include/Rcpp/sugar/functions/rowSums.h | 64 +++++----- inst/include/Rcpp/sugar/functions/sapply.h | 4 +- inst/include/Rcpp/sugar/functions/sd.h | 4 +- inst/include/Rcpp/sugar/functions/sign.h | 4 +- inst/include/Rcpp/sugar/functions/sum.h | 6 +- inst/include/Rcpp/sugar/functions/tail.h | 4 +- inst/include/Rcpp/sugar/functions/var.h | 8 +- inst/include/Rcpp/sugar/functions/which_max.h | 8 +- inst/include/Rcpp/sugar/functions/which_min.h | 8 +- inst/include/Rcpp/sugar/logical/and.h | 24 ++-- inst/include/Rcpp/sugar/logical/or.h | 24 ++-- inst/include/Rcpp/sugar/matrix/diag.h | 8 +- inst/include/Rcpp/sugar/nona/nona.h | 2 +- .../include/Rcpp/sugar/operators/Comparator.h | 18 +-- .../operators/Comparator_With_One_Value.h | 8 +- inst/include/Rcpp/sugar/operators/divides.h | 50 ++++---- inst/include/Rcpp/sugar/operators/minus.h | 48 ++++---- inst/include/Rcpp/sugar/operators/not.h | 4 +- inst/include/Rcpp/sugar/operators/plus.h | 48 ++++---- inst/include/Rcpp/sugar/operators/times.h | 48 ++++---- .../Rcpp/sugar/operators/unary_minus.h | 4 +- inst/include/Rcpp/traits/sugar_operand.h | 65 ++++++++++ inst/include/Rcpp/vector/MatrixBase.h | 4 + inst/include/RcppCommon.h | 1 + inst/tinytest/cpp/sugar_expressions.cpp | 112 ++++++++++++++++++ inst/tinytest/test_sugar.R | 19 +++ 61 files changed, 544 insertions(+), 343 deletions(-) create mode 100644 inst/include/Rcpp/traits/sugar_operand.h create mode 100644 inst/tinytest/cpp/sugar_expressions.cpp diff --git a/inst/include/Rcpp/stats/dpq/dpq.h b/inst/include/Rcpp/stats/dpq/dpq.h index c5721f06f..7aa7cff67 100644 --- a/inst/include/Rcpp/stats/dpq/dpq.h +++ b/inst/include/Rcpp/stats/dpq/dpq.h @@ -37,7 +37,7 @@ class D0 : public Rcpp::VectorBase< REALSXP, NA, D0 > { typedef double (*FunPtr)(double,int) ; D0( FunPtr ptr_, const VEC_TYPE& vec_, bool log_ ) : - ptr(ptr_), vec(vec_), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], log ); @@ -47,7 +47,7 @@ class D0 : public Rcpp::VectorBase< REALSXP, NA, D0 > { private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; int log; }; @@ -58,7 +58,7 @@ class D1 : public Rcpp::VectorBase< REALSXP, NA, D1 > { typedef double (*FunPtr)(double,double,int) ; D1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_ , bool log_) : - ptr(ptr_), vec(vec_), p0(p0_), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, log ); @@ -68,7 +68,7 @@ class D1 : public Rcpp::VectorBase< REALSXP, NA, D1 > { private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0 ; int log; } ; @@ -80,7 +80,7 @@ class D2 : public Rcpp::VectorBase< REALSXP, NA, D2 > { typedef double (*FunPtr)(double,double,double,int) ; D2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_ , bool log_) : - ptr(ptr_), vec(vec_), p0(p0_), p1(p1_), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, p1, log ); @@ -90,7 +90,7 @@ class D2 : public Rcpp::VectorBase< REALSXP, NA, D2 > { private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0, p1 ; int log; } ; @@ -102,7 +102,7 @@ class D3 : public Rcpp::VectorBase< REALSXP, NA, D3 > { typedef double (*FunPtr)(double,double,double,double,int) ; D3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_ , bool log_ ) : - ptr(ptr_), vec(vec_), p0(p0_), p1(p1_), p2(p2_), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), p2(p2_), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, p1, p2, log ); @@ -112,7 +112,7 @@ class D3 : public Rcpp::VectorBase< REALSXP, NA, D3 > { private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0, p1, p2 ; int log; } ; @@ -128,7 +128,7 @@ class P0 : public Rcpp::VectorBase< REALSXP, NA, P0 >{ P0( FunPtr ptr_, const VEC_TYPE& vec_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], lower, log ); @@ -138,7 +138,7 @@ class P0 : public Rcpp::VectorBase< REALSXP, NA, P0 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; int lower, log; }; @@ -152,7 +152,7 @@ class P1 : public Rcpp::VectorBase< REALSXP, NA, P1 >{ P1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), p0(p0_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, lower, log ); @@ -162,7 +162,7 @@ class P1 : public Rcpp::VectorBase< REALSXP, NA, P1 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0 ; int lower, log; @@ -177,7 +177,7 @@ class P2 : public Rcpp::VectorBase< REALSXP, NA, P2 >{ P2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), p0(p0_), p1(p1_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, p1, lower, log ); @@ -187,7 +187,7 @@ class P2 : public Rcpp::VectorBase< REALSXP, NA, P2 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0, p1 ; int lower, log; }; @@ -200,7 +200,7 @@ class P3 : public Rcpp::VectorBase< REALSXP, NA, P3 >{ P3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), p0(p0_), p1(p1_), p2(p2_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), p2(p2_), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, p1, p2, lower, log ); @@ -210,7 +210,7 @@ class P3 : public Rcpp::VectorBase< REALSXP, NA, P3 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0, p1,p2 ; int lower, log; @@ -226,7 +226,7 @@ class Q0 : public Rcpp::VectorBase< REALSXP, NA, Q0 >{ Q0( FunPtr ptr_, const VEC_TYPE& vec_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], lower, log ); @@ -236,7 +236,7 @@ class Q0 : public Rcpp::VectorBase< REALSXP, NA, Q0 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; int lower, log; }; @@ -249,7 +249,7 @@ class Q1 : public Rcpp::VectorBase< REALSXP, NA, Q1 >{ Q1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), p0(p0_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, lower, log ); @@ -259,7 +259,7 @@ class Q1 : public Rcpp::VectorBase< REALSXP, NA, Q1 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0 ; int lower, log; @@ -273,7 +273,7 @@ class Q2 : public Rcpp::VectorBase< REALSXP, NA, Q2 >{ Q2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), p0(p0_), p1(p1_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, p1, lower, log ); @@ -283,7 +283,7 @@ class Q2 : public Rcpp::VectorBase< REALSXP, NA, Q2 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0, p1 ; int lower, log; @@ -297,7 +297,7 @@ class Q3 : public Rcpp::VectorBase< REALSXP, NA, Q3 >{ Q3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_, bool lower_tail = true, bool log_ = false ) : - ptr(ptr_), vec(vec_), p0(p0_), p1(p1_), p2(p2_), lower(lower_tail), log(log_) {} + ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), p2(p2_), lower(lower_tail), log(log_) {} inline double operator[]( R_xlen_t i) const { return ptr( vec[i], p0, p1, p2, lower, log ); @@ -307,7 +307,7 @@ class Q3 : public Rcpp::VectorBase< REALSXP, NA, Q3 >{ private: FunPtr ptr ; - const VEC_TYPE& vec; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec; double p0, p1, p2 ; int lower, log; }; diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_1.h b/inst/include/Rcpp/sugar/block/SugarBlock_1.h index 78e0f8a4e..cbdbc0d2f 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_1.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_1.h @@ -29,7 +29,7 @@ template class SugarBlock_1 : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype , NA, SugarBlock_1 > { public: typedef RESULT_TYPE (*FunPtr)(U1) ; - SugarBlock_1( FunPtr ptr_, const T1 & vec_) : ptr(ptr_), vec(vec_){} + SugarBlock_1( FunPtr ptr_, const T1 & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { return ptr( vec[i] ) ; @@ -38,7 +38,7 @@ class SugarBlock_1 : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::type vec ; }; } // sugar diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_2.h b/inst/include/Rcpp/sugar/block/SugarBlock_2.h index d5f01ccb9..603473c60 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_2.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_2.h @@ -30,7 +30,7 @@ class SugarBlock_2 : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::type x ; + typename Rcpp::traits::sugar_operand< T2 >::type y ; }; @@ -51,7 +51,7 @@ class SugarBlock_2__VP : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_trait public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; SugarBlock_2__VP( FunPtr ptr_, const T1 & x_, U2 u2 ) : - ptr(ptr_), x(x_), y(u2){} + ptr(ptr_), x(x_.get_ref()), y(u2){} inline RESULT_TYPE operator[]( R_xlen_t i) const { return ptr( x[i], y ) ; @@ -60,7 +60,7 @@ class SugarBlock_2__VP : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_trait private: FunPtr ptr ; - const T1& x ; + typename Rcpp::traits::sugar_operand< T1 >::type x ; U2 y ; }; @@ -69,7 +69,7 @@ class SugarBlock_2__PV : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_trait public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; SugarBlock_2__PV( FunPtr ptr_, U1 u1, const T2& y_ ) : - ptr(ptr_), x(u1), y(y_){} + ptr(ptr_), x(u1), y(y_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { return ptr( x, y[i] ) ; @@ -79,7 +79,7 @@ class SugarBlock_2__PV : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_trait private: FunPtr ptr ; U1 x ; - const T2& y ; + typename Rcpp::traits::sugar_operand< T2 >::type y ; }; diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_3.h b/inst/include/Rcpp/sugar/block/SugarBlock_3.h index a12e4dbfd..5fc46c74c 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_3.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_3.h @@ -38,7 +38,7 @@ class SugarBlock_3_VVV : public Rcpp::VectorBase< public: typedef RESULT_TYPE (*FunPtr)(U1,U2,U3) ; SugarBlock_3_VVV( FunPtr ptr_, const T1 & x_, const T2& y_, const T3& z_ ) : - ptr(ptr_), x(x_), y(y_), z(z_) { + ptr(ptr_), x(x_.get_ref()), y(y_.get_ref()), z(z_.get_ref()) { // TODO: size checks, recycling, etc ... } inline RESULT_TYPE operator[]( R_xlen_t i) const { @@ -48,9 +48,9 @@ class SugarBlock_3_VVV : public Rcpp::VectorBase< private: FunPtr ptr ; - const T1& x ; - const T2& y ; - const T2& z ; + typename Rcpp::traits::sugar_operand< T1 >::type x ; + typename Rcpp::traits::sugar_operand< T2 >::type y ; + typename Rcpp::traits::sugar_operand< T3 >::type z ; }; diff --git a/inst/include/Rcpp/sugar/block/SugarMath.h b/inst/include/Rcpp/sugar/block/SugarMath.h index 624f2c569..4b0363c01 100644 --- a/inst/include/Rcpp/sugar/block/SugarMath.h +++ b/inst/include/Rcpp/sugar/block/SugarMath.h @@ -35,7 +35,7 @@ class SugarMath_1 : public Rcpp::VectorBase< typedef Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype ,NA,T1> VEC_TYPE ; - SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_){} + SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { U1 x = vec[i] ; @@ -46,7 +46,7 @@ class SugarMath_1 : public Rcpp::VectorBase< private: FunPtr ptr ; - const VEC_TYPE& vec ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec ; }; template @@ -58,7 +58,7 @@ class SugarMath_1 : public Rcpp::VectorBase< public: typedef Rcpp::VectorBase< INTSXP ,NA,T1> VEC_TYPE ; - SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_){} + SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { int x = vec[i] ; @@ -69,7 +69,7 @@ class SugarMath_1 : public Rcpp::VectorBase< private: FunPtr ptr ; - const VEC_TYPE& vec ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec ; }; template @@ -81,7 +81,7 @@ Rcpp::VectorBase< > { public: typedef Rcpp::VectorBase< INTSXP ,false,T1> VEC_TYPE ; - SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_){} + SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { return ptr( vec[i] ) ; @@ -90,7 +90,7 @@ Rcpp::VectorBase< private: FunPtr ptr ; - const VEC_TYPE& vec ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec ; }; diff --git a/inst/include/Rcpp/sugar/block/Vectorized_Math.h b/inst/include/Rcpp/sugar/block/Vectorized_Math.h index eb37acd4c..798571bb4 100644 --- a/inst/include/Rcpp/sugar/block/Vectorized_Math.h +++ b/inst/include/Rcpp/sugar/block/Vectorized_Math.h @@ -40,7 +40,7 @@ class Vectorized : public VectorBase >{ inline R_xlen_t size() const { return object.size(); } private: - const VEC_EXT& object ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type object ; } ; template @@ -58,7 +58,7 @@ class Vectorized_INTSXP : public VectorBase::type object ; } ; template class Vectorized_INTSXP : @@ -74,7 +74,7 @@ class Vectorized_INTSXP : inline R_xlen_t size() const { return object.size(); } private: - const VEC_EXT& object ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type object ; } ; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/all.h b/inst/include/Rcpp/sugar/functions/all.h index 9a6ffc469..4d61d624d 100644 --- a/inst/include/Rcpp/sugar/functions/all.h +++ b/inst/include/Rcpp/sugar/functions/all.h @@ -30,7 +30,7 @@ class All : public SingleLogicalResult< true, All >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef SingleLogicalResult< true, All > PARENT ; - All( const VEC_TYPE& t ) : PARENT() , object(t) {} + All( const VEC_TYPE& t ) : PARENT() , object(t.get_ref()) {} void apply(){ R_xlen_t n = object.size() ; @@ -51,7 +51,7 @@ class All : public SingleLogicalResult< true, All >{ } } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; @@ -61,7 +61,7 @@ class All : public SingleLogicalResult< false, All >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef SingleLogicalResult< false, All > PARENT ; - All( const VEC_TYPE& t ) : PARENT() , object(t) {} + All( const VEC_TYPE& t ) : PARENT() , object(t.get_ref()) {} void apply(){ R_xlen_t n = object.size() ; @@ -74,7 +74,7 @@ class All : public SingleLogicalResult< false, All >{ } } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; diff --git a/inst/include/Rcpp/sugar/functions/any.h b/inst/include/Rcpp/sugar/functions/any.h index dc242af5f..5f8fdcd01 100644 --- a/inst/include/Rcpp/sugar/functions/any.h +++ b/inst/include/Rcpp/sugar/functions/any.h @@ -30,7 +30,7 @@ class Any : public SingleLogicalResult< true, Any >{ public: typedef Rcpp::VectorBase VEC_TYPE ; typedef SingleLogicalResult< true , Any > PARENT ; - Any( const VEC_TYPE& t ) : PARENT() , object(t) {} + Any( const VEC_TYPE& t ) : PARENT() , object(t.get_ref()) {} void apply(){ R_xlen_t n = object.size() ; @@ -51,7 +51,7 @@ class Any : public SingleLogicalResult< true, Any >{ } } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; template @@ -59,7 +59,7 @@ class Any : public SingleLogicalResult< false, Any >{ public: typedef Rcpp::VectorBase VEC_TYPE ; typedef SingleLogicalResult< false , Any > PARENT ; - Any( const VEC_TYPE& t ) : PARENT() , object(t) {} + Any( const VEC_TYPE& t ) : PARENT() , object(t.get_ref()) {} void apply(){ R_xlen_t n = object.size() ; @@ -72,7 +72,7 @@ class Any : public SingleLogicalResult< false, Any >{ } } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/clamp.h b/inst/include/Rcpp/sugar/functions/clamp.h index 496df2e78..868386ea3 100644 --- a/inst/include/Rcpp/sugar/functions/clamp.h +++ b/inst/include/Rcpp/sugar/functions/clamp.h @@ -71,7 +71,7 @@ class Clamp_Primitive_Vector_Primitive : public VectorBase< inline R_xlen_t size() const { return vec.size() ; } private: - const T& vec ; + typename Rcpp::traits::sugar_operand< T >::type vec ; OPERATOR op ; } ; diff --git a/inst/include/Rcpp/sugar/functions/complex.h b/inst/include/Rcpp/sugar/functions/complex.h index 800c856fb..f897b5b87 100644 --- a/inst/include/Rcpp/sugar/functions/complex.h +++ b/inst/include/Rcpp/sugar/functions/complex.h @@ -36,7 +36,7 @@ class SugarComplex : public Rcpp::VectorBase< typedef Rcpp::VectorBase VEC_TYPE ; - SugarComplex( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_){} + SugarComplex( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { Rcomplex x = vec[i] ; @@ -48,7 +48,7 @@ class SugarComplex : public Rcpp::VectorBase< private: FunPtr ptr ; - const VEC_TYPE& vec ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type vec ; }; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/cummax.h b/inst/include/Rcpp/sugar/functions/cummax.h index 327dac60c..7695d7c06 100644 --- a/inst/include/Rcpp/sugar/functions/cummax.h +++ b/inst/include/Rcpp/sugar/functions/cummax.h @@ -32,7 +32,7 @@ class Cummax : public Lazy< Rcpp::Vector, Cummax > { typedef typename Rcpp::traits::storage_type::type STORAGE; typedef Rcpp::Vector VECTOR; - Cummax(const VEC_TYPE& object_) : object(object_) {} + Cummax(const VEC_TYPE& object_) : object(object_.get_ref()) {} VECTOR get() const { R_xlen_t n = object.size(); @@ -49,7 +49,7 @@ class Cummax : public Lazy< Rcpp::Vector, Cummax > { return result ; } private: - const VEC_TYPE& object; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object; }; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/cummin.h b/inst/include/Rcpp/sugar/functions/cummin.h index c4c864e0f..212a23afb 100644 --- a/inst/include/Rcpp/sugar/functions/cummin.h +++ b/inst/include/Rcpp/sugar/functions/cummin.h @@ -32,7 +32,7 @@ class Cummin : public Lazy< Rcpp::Vector, Cummin > { typedef typename Rcpp::traits::storage_type::type STORAGE; typedef Rcpp::Vector VECTOR; - Cummin(const VEC_TYPE& object_) : object(object_) {} + Cummin(const VEC_TYPE& object_) : object(object_.get_ref()) {} VECTOR get() const { R_xlen_t n = object.size(); @@ -49,7 +49,7 @@ class Cummin : public Lazy< Rcpp::Vector, Cummin > { return result ; } private: - const VEC_TYPE& object; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object; }; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/cumprod.h b/inst/include/Rcpp/sugar/functions/cumprod.h index 0ad8936fd..b09152624 100644 --- a/inst/include/Rcpp/sugar/functions/cumprod.h +++ b/inst/include/Rcpp/sugar/functions/cumprod.h @@ -33,7 +33,7 @@ class Cumprod : public Lazy< Rcpp::Vector, Cumprod > { typedef typename Rcpp::traits::storage_type::type STORAGE; typedef Rcpp::Vector VECTOR; - Cumprod(const VEC_TYPE& object_) : object(object_) {} + Cumprod(const VEC_TYPE& object_) : object(object_.get_ref()) {} VECTOR get() const { R_xlen_t n = object.size(); @@ -50,7 +50,7 @@ class Cumprod : public Lazy< Rcpp::Vector, Cumprod > { return result ; } private: - const VEC_TYPE& object; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object; }; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/cumsum.h b/inst/include/Rcpp/sugar/functions/cumsum.h index cb8e53886..f07801e5e 100644 --- a/inst/include/Rcpp/sugar/functions/cumsum.h +++ b/inst/include/Rcpp/sugar/functions/cumsum.h @@ -33,7 +33,7 @@ class Cumsum : public Lazy< Rcpp::Vector , Cumsum > { typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef Rcpp::Vector VECTOR ; - Cumsum( const VEC_TYPE& object_ ) : object(object_){} + Cumsum( const VEC_TYPE& object_ ) : object(object_.get_ref()){} VECTOR get() const { R_xlen_t n = object.size() ; @@ -51,7 +51,7 @@ class Cumsum : public Lazy< Rcpp::Vector , Cumsum > { return result ; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/diff.h b/inst/include/Rcpp/sugar/functions/diff.h index b6c43f3fd..add08741d 100644 --- a/inst/include/Rcpp/sugar/functions/diff.h +++ b/inst/include/Rcpp/sugar/functions/diff.h @@ -36,7 +36,7 @@ class Diff : public Rcpp::VectorBase< RTYPE, LHS_NA , Diff > typedef typename Rcpp::traits::storage_type::type STORAGE ; Diff( const LHS_TYPE& lhs_ ) : - lhs(lhs_), + lhs(lhs_.get_ref()), previous(lhs_[0]), previous_index(0), was_na(traits::is_na(previous)) @@ -66,7 +66,7 @@ class Diff : public Rcpp::VectorBase< RTYPE, LHS_NA , Diff > inline R_xlen_t size() const { return lhs.size() - 1 ; } private: - const LHS_TYPE& lhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; mutable STORAGE previous ; mutable R_xlen_t previous_index ; mutable bool was_na ; @@ -77,7 +77,7 @@ class Diff : public Rcpp::VectorBase< REALSXP, LHS_NA, D public: typedef typename Rcpp::VectorBase LHS_TYPE ; - Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs_[0]), previous_index(0) {} + Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_.get_ref()), previous(lhs_[0]), previous_index(0) {} inline double operator[]( R_xlen_t i ) const { double y = lhs[i+1] ; @@ -90,7 +90,7 @@ class Diff : public Rcpp::VectorBase< REALSXP, LHS_NA, D inline R_xlen_t size() const { return lhs.size() - 1 ; } private: - const LHS_TYPE& lhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; mutable double previous ; mutable R_xlen_t previous_index ; } ; @@ -101,7 +101,7 @@ class Diff : public Rcpp::VectorBase< RTYPE, false , Diff LHS_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_), previous(lhs[0]), previous_index(0) {} + Diff( const LHS_TYPE& lhs_ ) : lhs(lhs_.get_ref()), previous(lhs[0]), previous_index(0) {} inline STORAGE operator[]( R_xlen_t i ) const { STORAGE y = lhs[i+1] ; @@ -114,7 +114,7 @@ class Diff : public Rcpp::VectorBase< RTYPE, false , Diff::type lhs ; mutable STORAGE previous ; mutable R_xlen_t previous_index ; } ; diff --git a/inst/include/Rcpp/sugar/functions/head.h b/inst/include/Rcpp/sugar/functions/head.h index 32fa7a3ec..364ecdc65 100644 --- a/inst/include/Rcpp/sugar/functions/head.h +++ b/inst/include/Rcpp/sugar/functions/head.h @@ -32,7 +32,7 @@ class Head : public Rcpp::VectorBase< RTYPE ,NA, Head > { typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - Head( const VEC_TYPE& object_, R_xlen_t n_ ) : object(object_), n(n_) { + Head( const VEC_TYPE& object_, R_xlen_t n_ ) : object(object_.get_ref()), n(n_) { if( n < 0 ){ n = object.size() + n ; } @@ -44,7 +44,7 @@ class Head : public Rcpp::VectorBase< RTYPE ,NA, Head > { inline R_xlen_t size() const { return n; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; R_xlen_t n ; } ; diff --git a/inst/include/Rcpp/sugar/functions/ifelse.h b/inst/include/Rcpp/sugar/functions/ifelse.h index 1b58d2f41..340f79cb2 100644 --- a/inst/include/Rcpp/sugar/functions/ifelse.h +++ b/inst/include/Rcpp/sugar/functions/ifelse.h @@ -46,7 +46,7 @@ class IfElse : public VectorBase< // typedef typename Rcpp::traits::Extractor::type RHS_EXT ; IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { /* FIXME : cond, lhs and rhs must all have the same size */ RCPP_DEBUG( DEMANGLE(IfElse) ) ; @@ -62,9 +62,9 @@ class IfElse : public VectorBase< inline R_xlen_t size() const { return cond.size() ; } private: - const COND_TYPE& cond ; - const LHS_T& lhs ; - const RHS_T& rhs ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; + typename Rcpp::traits::sugar_operand< LHS_T >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_T >::type rhs ; } ; @@ -89,7 +89,7 @@ class IfElse : public VectorBase< typedef typename Rcpp::traits::Extractor::type RHS_EXT ; IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { /* FIXME : cond, lhs and rhs must all have the same size */ } @@ -102,9 +102,9 @@ class IfElse : public VectorBase< private: - const COND_TYPE& cond ; - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -129,7 +129,7 @@ class IfElse_Primitive_Vector : public VectorBase< typedef typename Rcpp::traits::Extractor::type RHS_EXT ; IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : - cond(cond_), lhs(lhs_), rhs(rhs_.get_ref()) { + cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { /* FIXME : cond, lhs and rhs must all have the sale size */ } @@ -143,9 +143,9 @@ class IfElse_Primitive_Vector : public VectorBase< inline R_xlen_t size() const { return cond.size() ; } private: - const COND_TYPE& cond ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; STORAGE lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -166,7 +166,7 @@ class IfElse_Primitive_Vector : public VectorBa typedef typename Rcpp::traits::Extractor::type RHS_EXT ; IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : - cond(cond_), lhs(lhs_), rhs(rhs_.get_ref()) { + cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { /* FIXME : cond, lhs and rhs must all have the same size */ } @@ -178,9 +178,9 @@ class IfElse_Primitive_Vector : public VectorBa inline R_xlen_t size() const { return cond.size() ; } private: - const COND_TYPE& cond ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; STORAGE lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -205,7 +205,7 @@ class IfElse_Vector_Primitive : public VectorBase< typedef typename Rcpp::traits::Extractor::type LHS_EXT ; IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : - cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_) { + cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { /* FIXME : cond, lhs and rhs must all have the same size */ } @@ -219,8 +219,8 @@ class IfElse_Vector_Primitive : public VectorBase< inline R_xlen_t size() const { return cond.size() ; } private: - const COND_TYPE& cond ; - const LHS_EXT& lhs ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; const STORAGE rhs ; } ; @@ -242,7 +242,7 @@ class IfElse_Vector_Primitive : public VectorBa typedef typename Rcpp::traits::Extractor::type LHS_EXT ; IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : - cond(cond_), lhs(lhs_.get_ref()), rhs(rhs_) { + cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { /* FIXME : cond, lhs and rhs must all have the sale size */ } @@ -254,8 +254,8 @@ class IfElse_Vector_Primitive : public VectorBa inline R_xlen_t size() const { return cond.size() ; } private: - const COND_TYPE& cond ; - const LHS_EXT& lhs ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; const STORAGE rhs ; } ; @@ -280,7 +280,7 @@ class IfElse_Primitive_Primitive : public VectorBase< typedef typename traits::storage_type::type STORAGE ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : - cond(cond_), lhs(lhs_), rhs(rhs_) { + cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { /* FIXME : cond, lhs and rhs must all have the same size */ } @@ -293,7 +293,7 @@ class IfElse_Primitive_Primitive : public VectorBase< inline R_xlen_t size() const { return cond.size() ; } private: - const COND_TYPE& cond ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; STORAGE lhs ; STORAGE rhs ; STORAGE na ; @@ -313,7 +313,7 @@ class IfElse_Primitive_Primitive : public VectorBase< typedef typename traits::storage_type::type STORAGE ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : - cond(cond_), lhs(lhs_), rhs(rhs_) { + cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { /* FIXME : cond, lhs and rhs must all have the same size */ } @@ -324,7 +324,7 @@ class IfElse_Primitive_Primitive : public VectorBase< inline R_xlen_t size() const { return cond.size() ; } private: - const COND_TYPE& cond ; + typename Rcpp::traits::sugar_operand< COND_TYPE >::type cond ; STORAGE lhs ; STORAGE rhs ; diff --git a/inst/include/Rcpp/sugar/functions/is_finite.h b/inst/include/Rcpp/sugar/functions/is_finite.h index 1fc68191b..9ed8cf332 100644 --- a/inst/include/Rcpp/sugar/functions/is_finite.h +++ b/inst/include/Rcpp/sugar/functions/is_finite.h @@ -38,7 +38,7 @@ class IsFinite : public ::Rcpp::VectorBase< LGLSXP, false, IsFinite::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/functions/is_infinite.h b/inst/include/Rcpp/sugar/functions/is_infinite.h index 6806683dc..43ffd71e1 100644 --- a/inst/include/Rcpp/sugar/functions/is_infinite.h +++ b/inst/include/Rcpp/sugar/functions/is_infinite.h @@ -38,7 +38,7 @@ class IsInfinite : public ::Rcpp::VectorBase< LGLSXP, false, IsInfinite::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/functions/is_na.h b/inst/include/Rcpp/sugar/functions/is_na.h index 01570e9bc..345cff359 100644 --- a/inst/include/Rcpp/sugar/functions/is_na.h +++ b/inst/include/Rcpp/sugar/functions/is_na.h @@ -32,7 +32,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsNa > typedef typename traits::storage_type::type STORAGE ; typedef Rcpp::VectorBase BASE ; - IsNa( const BASE& obj_) : obj(obj_){} + IsNa( const BASE& obj_) : obj(obj_.get_ref()){} inline int operator[]( R_xlen_t i ) const { return ::Rcpp::traits::is_na( obj[i] ) ; @@ -41,7 +41,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsNa > inline R_xlen_t size() const { return obj.size() ; } private: - const BASE& obj ; + typename Rcpp::traits::sugar_operand< BASE >::type obj ; } ; @@ -54,7 +54,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsN typedef typename traits::storage_type::type STORAGE ; typedef Rcpp::VectorBase BASE ; - IsNa( const BASE& obj_) : obj(obj_){} + IsNa( const BASE& obj_) : obj(obj_.get_ref()){} inline int operator[]( R_xlen_t /*i*/ ) const { return FALSE ; @@ -63,7 +63,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsN inline R_xlen_t size() const { return obj.size() ; } private: - const BASE& obj ; + typename Rcpp::traits::sugar_operand< BASE >::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/functions/is_nan.h b/inst/include/Rcpp/sugar/functions/is_nan.h index 686fc0dcb..a5dfb1e1e 100644 --- a/inst/include/Rcpp/sugar/functions/is_nan.h +++ b/inst/include/Rcpp/sugar/functions/is_nan.h @@ -38,7 +38,7 @@ class IsNaN : public ::Rcpp::VectorBase< LGLSXP, false, IsNaN inline R_xlen_t size() const { return obj.size() ; } private: - const VEC_TYPE& obj ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/functions/lapply.h b/inst/include/Rcpp/sugar/functions/lapply.h index 7d098010e..21cd7ef3a 100644 --- a/inst/include/Rcpp/sugar/functions/lapply.h +++ b/inst/include/Rcpp/sugar/functions/lapply.h @@ -37,7 +37,7 @@ class Lapply : public VectorBase< typedef typename ::Rcpp::traits::result_of::type result_type ; Lapply( const VEC& vec_, Function fun_ ) : - vec(vec_), fun(fun_){} + vec(vec_.get_ref()), fun(fun_){} inline SEXP operator[]( R_xlen_t i ) const { return Rcpp::wrap( fun( vec[i] ) ); @@ -45,7 +45,7 @@ class Lapply : public VectorBase< inline R_xlen_t size() const { return vec.size() ; } private: - const VEC& vec ; + typename Rcpp::traits::sugar_operand< VEC >::type vec ; Function fun ; } ; diff --git a/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h b/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h index 8185f6220..89e040020 100644 --- a/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h +++ b/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h @@ -50,8 +50,8 @@ class Mapply_2 : public VectorBase< inline R_xlen_t size() const { return vec_1.size() ; } private: - const T_1& vec_1 ; - const T_2& vec_2 ; + typename Rcpp::traits::sugar_operand< T_1 >::type vec_1 ; + typename Rcpp::traits::sugar_operand< T_2 >::type vec_2 ; Function fun ; } ; @@ -81,7 +81,7 @@ class Mapply_2_Vector_Primitive : public inline R_xlen_t size() const { return vec_1.size() ; } private: - const T_1& vec_1 ; + typename Rcpp::traits::sugar_operand< T_1 >::type vec_1 ; PRIM_2 prim_2 ; Function fun ; } ; @@ -113,7 +113,7 @@ class Mapply_2_Primitive_Vector : public private: PRIM_1 prim_1 ; - const T_2& vec_2 ; + typename Rcpp::traits::sugar_operand< T_2 >::type vec_2 ; Function fun ; } ; diff --git a/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h b/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h index e009b9142..cecfa3bfb 100644 --- a/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h +++ b/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h @@ -59,9 +59,9 @@ class Mapply_3 : public VectorBase< inline R_xlen_t size() const { return vec_1.size() ; } private: - const EXT_1& vec_1 ; - const EXT_2& vec_2 ; - const EXT_3& vec_3 ; + typename Rcpp::traits::sugar_operand< EXT_1 >::type vec_1 ; + typename Rcpp::traits::sugar_operand< EXT_2 >::type vec_2 ; + typename Rcpp::traits::sugar_operand< EXT_3 >::type vec_3 ; Function fun ; } ; diff --git a/inst/include/Rcpp/sugar/functions/max.h b/inst/include/Rcpp/sugar/functions/max.h index 7f85b1457..d370d74e8 100644 --- a/inst/include/Rcpp/sugar/functions/max.h +++ b/inst/include/Rcpp/sugar/functions/max.h @@ -52,7 +52,7 @@ namespace sugar{ } private: - const T& obj ; + typename Rcpp::traits::sugar_operand< T >::type obj ; } ; // version for NA = false @@ -81,7 +81,7 @@ namespace sugar{ } private: - const T& obj ; + typename Rcpp::traits::sugar_operand< T >::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/functions/mean.h b/inst/include/Rcpp/sugar/functions/mean.h index 1ffde0d37..87ccef54a 100644 --- a/inst/include/Rcpp/sugar/functions/mean.h +++ b/inst/include/Rcpp/sugar/functions/mean.h @@ -29,7 +29,7 @@ class Mean : public Lazy > { typedef typename Rcpp::VectorBase VEC_TYPE; typedef Rcpp::Vector VECTOR; - Mean(const VEC_TYPE& object_) : object(object_) {} + Mean(const VEC_TYPE& object_) : object(object_.get_ref()) {} double get() const { VECTOR input = object; @@ -46,7 +46,7 @@ class Mean : public Lazy > { return (double)s ; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; }; template @@ -54,7 +54,7 @@ class Mean : public Lazy > { public: typedef typename Rcpp::VectorBase VEC_TYPE; - Mean(const VEC_TYPE& object_) : object(object_) {} + Mean(const VEC_TYPE& object_) : object(object_.get_ref()) {} Rcomplex get() const { ComplexVector input = object; @@ -83,7 +83,7 @@ class Mean : public Lazy > { return z; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; }; template @@ -91,7 +91,7 @@ class Mean : public Lazy > { public: typedef typename Rcpp::VectorBase VEC_TYPE; - Mean(const VEC_TYPE& object_) : object(object_) {} + Mean(const VEC_TYPE& object_) : object(object_.get_ref()) {} double get() const { LogicalVector input = object; @@ -105,7 +105,7 @@ class Mean : public Lazy > { return (double)s; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; }; template @@ -113,7 +113,7 @@ class Mean : public Lazy > { public: typedef typename Rcpp::VectorBase VEC_TYPE; - Mean(const VEC_TYPE& object_) : object(object_) {} + Mean(const VEC_TYPE& object_) : object(object_.get_ref()) {} double get() const { IntegerVector input = object; @@ -129,7 +129,7 @@ class Mean : public Lazy > { return (double)s ; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; }; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/min.h b/inst/include/Rcpp/sugar/functions/min.h index 0e8b9410e..18bb44543 100644 --- a/inst/include/Rcpp/sugar/functions/min.h +++ b/inst/include/Rcpp/sugar/functions/min.h @@ -52,7 +52,7 @@ namespace sugar{ return min ; } - const T& obj ; + typename Rcpp::traits::sugar_operand< T >::type obj ; } ; // version for NA = false @@ -80,7 +80,7 @@ namespace sugar{ return min ; } - const T& obj ; + typename Rcpp::traits::sugar_operand< T >::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/functions/pmax.h b/inst/include/Rcpp/sugar/functions/pmax.h index a695906de..775ee7555 100644 --- a/inst/include/Rcpp/sugar/functions/pmax.h +++ b/inst/include/Rcpp/sugar/functions/pmax.h @@ -113,8 +113,8 @@ class Pmax_Vector_Vector : public VectorBase< inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_T& lhs ; - const RHS_T& rhs ; + typename Rcpp::traits::sugar_operand< LHS_T >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_T >::type rhs ; OPERATOR op ; } ; @@ -141,7 +141,7 @@ class Pmax_Vector_Primitive : public VectorBase< inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_T& lhs ; + typename Rcpp::traits::sugar_operand< LHS_T >::type lhs ; OPERATOR op ; } ; diff --git a/inst/include/Rcpp/sugar/functions/pmin.h b/inst/include/Rcpp/sugar/functions/pmin.h index 92cb920a3..78e94abf7 100644 --- a/inst/include/Rcpp/sugar/functions/pmin.h +++ b/inst/include/Rcpp/sugar/functions/pmin.h @@ -113,8 +113,8 @@ class Pmin_Vector_Vector : public VectorBase< inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_T& lhs ; - const RHS_T& rhs ; + typename Rcpp::traits::sugar_operand< LHS_T >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_T >::type rhs ; OPERATOR op ; } ; @@ -139,7 +139,7 @@ class Pmin_Vector_Primitive : public VectorBase< inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_T& lhs ; + typename Rcpp::traits::sugar_operand< LHS_T >::type lhs ; OPERATOR op ; } ; diff --git a/inst/include/Rcpp/sugar/functions/pow.h b/inst/include/Rcpp/sugar/functions/pow.h index 79a5c81bf..38204726c 100644 --- a/inst/include/Rcpp/sugar/functions/pow.h +++ b/inst/include/Rcpp/sugar/functions/pow.h @@ -38,7 +38,7 @@ class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow inline R_xlen_t size() const { return object.size() ; } private: - const T& object ; + typename Rcpp::traits::sugar_operand< T >::type object ; EXPONENT_TYPE op ; } ; @@ -54,7 +54,7 @@ class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow inline R_xlen_t size() const { return object.size() ; } private: - const T& object ; + typename Rcpp::traits::sugar_operand< T >::type object ; EXPONENT_TYPE op ; } ; template @@ -68,7 +68,7 @@ class Pow : public Rcpp::VectorBase< REALSXP ,fals inline R_xlen_t size() const { return object.size() ; } private: - const T& object ; + typename Rcpp::traits::sugar_operand< T >::type object ; EXPONENT_TYPE op ; } ; diff --git a/inst/include/Rcpp/sugar/functions/range.h b/inst/include/Rcpp/sugar/functions/range.h index 50ceb8eee..1474bd3c4 100644 --- a/inst/include/Rcpp/sugar/functions/range.h +++ b/inst/include/Rcpp/sugar/functions/range.h @@ -49,7 +49,7 @@ namespace sugar{ private: - const T& obj ; + typename Rcpp::traits::sugar_operand< T >::type obj ; STORAGE min_, max_, current ; } ; @@ -75,7 +75,7 @@ namespace sugar{ private: - const T& obj ; + typename Rcpp::traits::sugar_operand< T >::type obj ; STORAGE min_, max_, current ; } ; diff --git a/inst/include/Rcpp/sugar/functions/rep.h b/inst/include/Rcpp/sugar/functions/rep.h index 47c1194ca..4b3445bd7 100644 --- a/inst/include/Rcpp/sugar/functions/rep.h +++ b/inst/include/Rcpp/sugar/functions/rep.h @@ -32,7 +32,7 @@ class Rep : public Rcpp::VectorBase< RTYPE ,NA, Rep > { typedef typename Rcpp::traits::storage_type::type STORAGE ; Rep( const VEC_TYPE& object_, R_xlen_t times_ ) : - object(object_), times(times_), n(object_.size()){} + object(object_.get_ref()), times(times_), n(object_.size()){} inline STORAGE operator[]( R_xlen_t i ) const { return object[ i % n ] ; @@ -40,7 +40,7 @@ class Rep : public Rcpp::VectorBase< RTYPE ,NA, Rep > { inline R_xlen_t size() const { return times * n ; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; R_xlen_t times, n ; } ; @@ -59,7 +59,7 @@ class Rep_Single : public Rcpp::VectorBase< inline R_xlen_t size() const { return n ; } private: - const T& x ; + typename Rcpp::traits::sugar_operand< T >::type x ; R_xlen_t n; } ; diff --git a/inst/include/Rcpp/sugar/functions/rep_each.h b/inst/include/Rcpp/sugar/functions/rep_each.h index a0c0d0744..c6e0b8aad 100644 --- a/inst/include/Rcpp/sugar/functions/rep_each.h +++ b/inst/include/Rcpp/sugar/functions/rep_each.h @@ -32,7 +32,7 @@ class Rep_each : public Rcpp::VectorBase< RTYPE ,NA, Rep_each > { typedef typename Rcpp::traits::storage_type::type STORAGE ; Rep_each( const VEC_TYPE& object_, R_xlen_t times_ ) : - object(object_), times(times_), n(object.size()) {} + object(object_.get_ref()), times(times_), n(object.size()) {} inline STORAGE operator[]( R_xlen_t i ) const { return object[ i / times ] ; @@ -40,7 +40,7 @@ class Rep_each : public Rcpp::VectorBase< RTYPE ,NA, Rep_each > { inline R_xlen_t size() const { return n * times ; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; R_xlen_t times, n ; } ; diff --git a/inst/include/Rcpp/sugar/functions/rep_len.h b/inst/include/Rcpp/sugar/functions/rep_len.h index 1332a3422..b557d0959 100644 --- a/inst/include/Rcpp/sugar/functions/rep_len.h +++ b/inst/include/Rcpp/sugar/functions/rep_len.h @@ -32,7 +32,7 @@ class Rep_len : public Rcpp::VectorBase< RTYPE ,NA, Rep_len > { typedef typename Rcpp::traits::storage_type::type STORAGE ; Rep_len( const VEC_TYPE& object_, R_xlen_t len_ ) : - object(object_), len(len_), n(object_.size()){} + object(object_.get_ref()), len(len_), n(object_.size()){} inline STORAGE operator[]( R_xlen_t i ) const { return object[ i % n ] ; @@ -40,7 +40,7 @@ class Rep_len : public Rcpp::VectorBase< RTYPE ,NA, Rep_len > { inline R_xlen_t size() const { return len ; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; R_xlen_t len, n ; } ; diff --git a/inst/include/Rcpp/sugar/functions/rev.h b/inst/include/Rcpp/sugar/functions/rev.h index 59e225659..e1f29a3b4 100644 --- a/inst/include/Rcpp/sugar/functions/rev.h +++ b/inst/include/Rcpp/sugar/functions/rev.h @@ -32,7 +32,7 @@ class Rev : public Rcpp::VectorBase< RTYPE ,NA, Rev > { typedef typename Rcpp::traits::storage_type::type STORAGE ; Rev( const VEC_TYPE& object_ ) : - object(object_), n(object_.size() - 1) {} + object(object_.get_ref()), n(object_.size() - 1) {} inline STORAGE operator[]( R_xlen_t i ) const { return object[n - i] ; @@ -40,7 +40,7 @@ class Rev : public Rcpp::VectorBase< RTYPE ,NA, Rev > { inline R_xlen_t size() const { return n + 1; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; R_xlen_t n ; } ; diff --git a/inst/include/Rcpp/sugar/functions/rowSums.h b/inst/include/Rcpp/sugar/functions/rowSums.h index 2afcd954b..0a1ae85ce 100644 --- a/inst/include/Rcpp/sugar/functions/rowSums.h +++ b/inst/include/Rcpp/sugar/functions/rowSums.h @@ -108,7 +108,7 @@ template class RowSumsImpl : public Lazy::type, RowSumsImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::RowSumsReturn return_traits; typedef typename return_traits::type return_vector; @@ -116,7 +116,7 @@ class RowSumsImpl : public: RowSumsImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -152,7 +152,7 @@ template class RowSumsImpl<__RTYPE__, NA, T, NA_RM> : \ public Lazy::type, RowSumsImpl<__RTYPE__, NA, T, NA_RM> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::RowSumsReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -160,7 +160,7 @@ private: \ public: \ RowSumsImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ @@ -195,7 +195,7 @@ template class RowSumsImpl : public Lazy::type, RowSumsImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::RowSumsReturn return_traits; typedef typename return_traits::type return_vector; @@ -203,7 +203,7 @@ class RowSumsImpl : public: RowSumsImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -236,7 +236,7 @@ template class RowSumsImpl<__RTYPE__, NA, T, true> : \ public Lazy::type, RowSumsImpl<__RTYPE__, NA, T, true> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::RowSumsReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -244,7 +244,7 @@ private: \ public: \ RowSumsImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ @@ -289,7 +289,7 @@ template class ColSumsImpl : public Lazy::type, ColSumsImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::ColSumsReturn return_traits; typedef typename return_traits::type return_vector; @@ -297,7 +297,7 @@ class ColSumsImpl : public: ColSumsImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -325,7 +325,7 @@ template class ColSumsImpl<__RTYPE__, NA, T, NA_RM> : \ public Lazy::type, ColSumsImpl<__RTYPE__, NA, T, NA_RM> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::ColSumsReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -333,7 +333,7 @@ private: \ public: \ ColSumsImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ @@ -368,7 +368,7 @@ template class ColSumsImpl : public Lazy::type, ColSumsImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::ColSumsReturn return_traits; typedef typename return_traits::type return_vector; @@ -376,7 +376,7 @@ class ColSumsImpl : public: ColSumsImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -409,7 +409,7 @@ template class ColSumsImpl<__RTYPE__, NA, T, true> : \ public Lazy::type, ColSumsImpl<__RTYPE__, NA, T, true> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::ColSumsReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -417,7 +417,7 @@ private: \ public: \ ColSumsImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ @@ -465,7 +465,7 @@ template class RowMeansImpl : public Lazy::type, RowMeansImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::RowMeansReturn return_traits; typedef typename return_traits::type return_vector; @@ -473,7 +473,7 @@ class RowMeansImpl : public: RowMeansImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -505,7 +505,7 @@ template class RowMeansImpl<__RTYPE__, NA, T, NA_RM> : \ public Lazy::type, RowMeansImpl<__RTYPE__, NA, T, NA_RM> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::RowMeansReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -513,7 +513,7 @@ private: \ public: \ RowMeansImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ @@ -552,7 +552,7 @@ template class RowMeansImpl : public Lazy::type, RowMeansImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::RowMeansReturn return_traits; typedef typename return_traits::type return_vector; @@ -560,7 +560,7 @@ class RowMeansImpl : public: RowMeansImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -604,7 +604,7 @@ template class RowMeansImpl<__RTYPE__, NA, T, true> : \ public Lazy::type, RowMeansImpl<__RTYPE__, NA, T, true> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::RowMeansReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -612,7 +612,7 @@ private: \ public: \ RowMeansImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ @@ -665,7 +665,7 @@ template class ColMeansImpl : public Lazy::type, ColMeansImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::ColMeansReturn return_traits; typedef typename return_traits::type return_vector; @@ -673,7 +673,7 @@ class ColMeansImpl : public: ColMeansImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -705,7 +705,7 @@ template class ColMeansImpl<__RTYPE__, NA, T, NA_RM> : \ public Lazy::type, ColMeansImpl<__RTYPE__, NA, T, NA_RM> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::ColMeansReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -713,7 +713,7 @@ private: \ public: \ ColMeansImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ @@ -752,7 +752,7 @@ template class ColMeansImpl : public Lazy::type, ColMeansImpl > { private: - const MatrixBase& ref; + typename Rcpp::traits::sugar_operand< MatrixBase >::type ref; typedef detail::ColMeansReturn return_traits; typedef typename return_traits::type return_vector; @@ -760,7 +760,7 @@ class ColMeansImpl : public: ColMeansImpl(const MatrixBase& ref_) - : ref(ref_) + : ref(ref_.get_ref()) {} return_vector get() const { @@ -804,7 +804,7 @@ template class ColMeansImpl<__RTYPE__, NA, T, true> : \ public Lazy::type, ColMeansImpl<__RTYPE__, NA, T, true> > { \ private: \ - const MatrixBase<__RTYPE__, NA, T>& ref; \ + typename Rcpp::traits::sugar_operand< MatrixBase<__RTYPE__, NA, T> >::type ref; \ \ typedef detail::ColMeansReturn<__RTYPE__> return_traits; \ typedef typename return_traits::type return_vector; \ @@ -812,7 +812,7 @@ private: \ public: \ ColMeansImpl(const MatrixBase<__RTYPE__, NA, T>& ref_) \ - : ref(ref_) \ + : ref(ref_.get_ref()) \ {} \ \ return_vector get() const { \ diff --git a/inst/include/Rcpp/sugar/functions/sapply.h b/inst/include/Rcpp/sugar/functions/sapply.h index 5b1311c5e..5f1a7d803 100644 --- a/inst/include/Rcpp/sugar/functions/sapply.h +++ b/inst/include/Rcpp/sugar/functions/sapply.h @@ -56,7 +56,7 @@ class Sapply : public VectorBase< inline R_xlen_t size() const { return vec.size() ; } private: - const EXT& vec ; + typename Rcpp::traits::sugar_operand< EXT >::type vec ; Function fun ; } ; @@ -90,7 +90,7 @@ class Sapply : public VectorBase< inline R_xlen_t size() const { return vec.size() ; } private: - const EXT& vec ; + typename Rcpp::traits::sugar_operand< EXT >::type vec ; Function fun ; } ; diff --git a/inst/include/Rcpp/sugar/functions/sd.h b/inst/include/Rcpp/sugar/functions/sd.h index d7da4d600..e721e4c73 100644 --- a/inst/include/Rcpp/sugar/functions/sd.h +++ b/inst/include/Rcpp/sugar/functions/sd.h @@ -31,13 +31,13 @@ class Sd : public Lazy< typename Rcpp::traits::storage_type::type , Sd VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - Sd( const VEC_TYPE& object_ ) : object(object_){} + Sd( const VEC_TYPE& object_ ) : object(object_.get_ref()){} STORAGE get() const { return ::sqrt( var(object).get() ) ; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/sign.h b/inst/include/Rcpp/sugar/functions/sign.h index 83ad71ae0..86273bbb8 100644 --- a/inst/include/Rcpp/sugar/functions/sign.h +++ b/inst/include/Rcpp/sugar/functions/sign.h @@ -51,7 +51,7 @@ class Sign : public Rcpp::VectorBase< INTSXP,NA, Sign > { typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef int r_import_type ; - Sign( const VEC_TYPE& object_ ) : object(object_){} + Sign( const VEC_TYPE& object_ ) : object(object_.get_ref()){} inline int operator[]( R_xlen_t i ) const { return get(i) ; @@ -61,7 +61,7 @@ class Sign : public Rcpp::VectorBase< INTSXP,NA, Sign > { operator SEXP() const { return wrap( *this ); } inline int get(R_xlen_t i) const { return sign__impl::get( object[i] ); } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/sum.h b/inst/include/Rcpp/sugar/functions/sum.h index fac5d10d4..df51c076d 100644 --- a/inst/include/Rcpp/sugar/functions/sum.h +++ b/inst/include/Rcpp/sugar/functions/sum.h @@ -48,7 +48,7 @@ class Sum : public Lazy< typename Rcpp::traits::storage_type::type , Sum< return result ; } private: - const VEC_EXT& object ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type object ; } ; // RTYPE = REALSXP template @@ -68,7 +68,7 @@ class Sum : public Lazy< double , Sum > { return result ; } private: - const VEC_EXT& object ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type object ; } ; @@ -90,7 +90,7 @@ class Sum : public Lazy< typename Rcpp::traits::storage_type::type object ; } ; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/tail.h b/inst/include/Rcpp/sugar/functions/tail.h index 3bfe830f1..de8be4416 100644 --- a/inst/include/Rcpp/sugar/functions/tail.h +++ b/inst/include/Rcpp/sugar/functions/tail.h @@ -31,7 +31,7 @@ class Tail : public Rcpp::VectorBase< RTYPE ,NA, Tail > { typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - Tail( const VEC_TYPE& object_, R_xlen_t n_ ) : object(object_), start(0), n(n_) { + Tail( const VEC_TYPE& object_, R_xlen_t n_ ) : object(object_.get_ref()), start(0), n(n_) { if( n > 0 ){ start = object.size() - n ; } else { @@ -46,7 +46,7 @@ class Tail : public Rcpp::VectorBase< RTYPE ,NA, Tail > { inline R_xlen_t size() const { return n; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; R_xlen_t start, n ; } ; diff --git a/inst/include/Rcpp/sugar/functions/var.h b/inst/include/Rcpp/sugar/functions/var.h index 6e064c66a..afee1805d 100644 --- a/inst/include/Rcpp/sugar/functions/var.h +++ b/inst/include/Rcpp/sugar/functions/var.h @@ -32,7 +32,7 @@ class Var : public Lazy< double , Var > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; - Var( const VEC_TYPE& object_ ) : object(object_){} + Var( const VEC_TYPE& object_ ) : object(object_.get_ref()){} double get() const{ const double average = mean(object).get(); @@ -44,7 +44,7 @@ class Var : public Lazy< double , Var > { } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; template @@ -52,7 +52,7 @@ class Var : public Lazy< double , Var > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; - Var( const VEC_TYPE& object_ ) : object(object_){} + Var( const VEC_TYPE& object_ ) : object(object_.get_ref()){} double get() const{ const Rcomplex average = mean(object).get(); @@ -66,7 +66,7 @@ class Var : public Lazy< double , Var > { } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; } ; } // sugar diff --git a/inst/include/Rcpp/sugar/functions/which_max.h b/inst/include/Rcpp/sugar/functions/which_max.h index 165ad6a81..a92247a1e 100644 --- a/inst/include/Rcpp/sugar/functions/which_max.h +++ b/inst/include/Rcpp/sugar/functions/which_max.h @@ -30,7 +30,7 @@ class WhichMax { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - WhichMax(const VEC_TYPE& obj_ ) : obj(obj_){} + WhichMax(const VEC_TYPE& obj_ ) : obj(obj_.get_ref()){} R_xlen_t get() const { STORAGE current = obj[0] ; @@ -50,7 +50,7 @@ class WhichMax { } private: - const VEC_TYPE& obj ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type obj ; } ; @@ -59,7 +59,7 @@ class WhichMax { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - WhichMax(const VEC_TYPE& obj_ ) : obj(obj_){} + WhichMax(const VEC_TYPE& obj_ ) : obj(obj_.get_ref()){} R_xlen_t get() const { STORAGE current = obj[0] ; @@ -77,7 +77,7 @@ class WhichMax { } private: - const VEC_TYPE& obj ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/functions/which_min.h b/inst/include/Rcpp/sugar/functions/which_min.h index cbc8c145f..7dd5f52ad 100644 --- a/inst/include/Rcpp/sugar/functions/which_min.h +++ b/inst/include/Rcpp/sugar/functions/which_min.h @@ -30,7 +30,7 @@ class WhichMin { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - WhichMin(const VEC_TYPE& obj_ ) : obj(obj_){} + WhichMin(const VEC_TYPE& obj_ ) : obj(obj_.get_ref()){} R_xlen_t get() const { STORAGE current = obj[0] ; @@ -50,7 +50,7 @@ class WhichMin { } private: - const VEC_TYPE& obj ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type obj ; } ; @@ -59,7 +59,7 @@ class WhichMin { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - WhichMin(const VEC_TYPE& obj_ ) : obj(obj_){} + WhichMin(const VEC_TYPE& obj_ ) : obj(obj_.get_ref()){} R_xlen_t get() const { STORAGE current = obj[0] ; @@ -77,7 +77,7 @@ class WhichMin { } private: - const VEC_TYPE& obj ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type obj ; } ; diff --git a/inst/include/Rcpp/sugar/logical/and.h b/inst/include/Rcpp/sugar/logical/and.h index faa925f4f..7738af424 100644 --- a/inst/include/Rcpp/sugar/logical/and.h +++ b/inst/include/Rcpp/sugar/logical/and.h @@ -207,7 +207,7 @@ class And_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; @@ -217,8 +217,8 @@ class And_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; template class And_LogicalExpression_LogicalExpression @@ -227,7 +227,7 @@ class And_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; @@ -237,8 +237,8 @@ class And_LogicalExpression_LogicalExpression inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; template class And_LogicalExpression_LogicalExpression @@ -247,7 +247,7 @@ class And_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; @@ -257,8 +257,8 @@ class And_LogicalExpression_LogicalExpression inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; template class And_LogicalExpression_LogicalExpression @@ -267,7 +267,7 @@ class And_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; @@ -276,8 +276,8 @@ class And_LogicalExpression_LogicalExpression inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; } diff --git a/inst/include/Rcpp/sugar/logical/or.h b/inst/include/Rcpp/sugar/logical/or.h index 5ad28b897..9ba1d2748 100644 --- a/inst/include/Rcpp/sugar/logical/or.h +++ b/inst/include/Rcpp/sugar/logical/or.h @@ -204,7 +204,7 @@ class Or_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; @@ -214,8 +214,8 @@ class Or_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; template class Or_LogicalExpression_LogicalExpression @@ -224,7 +224,7 @@ class Or_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; @@ -234,8 +234,8 @@ class Or_LogicalExpression_LogicalExpression inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; template class Or_LogicalExpression_LogicalExpression @@ -244,7 +244,7 @@ class Or_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; @@ -254,8 +254,8 @@ class Or_LogicalExpression_LogicalExpression inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; template class Or_LogicalExpression_LogicalExpression @@ -264,7 +264,7 @@ class Or_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; @@ -273,8 +273,8 @@ class Or_LogicalExpression_LogicalExpression inline R_xlen_t size() const { return lhs.size(); } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; } ; diff --git a/inst/include/Rcpp/sugar/matrix/diag.h b/inst/include/Rcpp/sugar/matrix/diag.h index af2941645..8aa4ca815 100644 --- a/inst/include/Rcpp/sugar/matrix/diag.h +++ b/inst/include/Rcpp/sugar/matrix/diag.h @@ -32,7 +32,7 @@ class Diag_Extractor : public Rcpp::VectorBase< RTYPE ,NA, Diag_Extractor MAT_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - Diag_Extractor( const MAT_TYPE& object_ ) : object(object_), n(0) { + Diag_Extractor( const MAT_TYPE& object_ ) : object(object_.get_ref()), n(0) { int nr = static_cast(object.nrow()) ; int nc = static_cast(object.ncol()) ; n = (nc < nr ) ? nc : nr ; @@ -44,7 +44,7 @@ class Diag_Extractor : public Rcpp::VectorBase< RTYPE ,NA, Diag_Extractor::type object ; R_xlen_t n ; } ; @@ -55,7 +55,7 @@ class Diag_Maker : public Rcpp::MatrixBase< RTYPE ,NA, Diag_Maker > typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - Diag_Maker( const VEC_TYPE& object_ ) : object(object_), n(static_cast(object_.size())) {} + Diag_Maker( const VEC_TYPE& object_ ) : object(object_.get_ref()), n(static_cast(object_.size())) {} inline STORAGE operator()( int i, int j ) const { return (i==j) ? object[i] : 0 ; @@ -65,7 +65,7 @@ class Diag_Maker : public Rcpp::MatrixBase< RTYPE ,NA, Diag_Maker > inline int nrow() const { return n; } private: - const VEC_TYPE& object ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type object ; int n ; } ; diff --git a/inst/include/Rcpp/sugar/nona/nona.h b/inst/include/Rcpp/sugar/nona/nona.h index 6eef297e4..865b876b8 100644 --- a/inst/include/Rcpp/sugar/nona/nona.h +++ b/inst/include/Rcpp/sugar/nona/nona.h @@ -37,7 +37,7 @@ namespace sugar { inline STORAGE operator[](R_xlen_t i) const { return data[i] ; } private: - const VECTOR& data ; + typename Rcpp::traits::sugar_operand< VECTOR >::type data ; } ; // specialization when the expression is actually a vector expression diff --git a/inst/include/Rcpp/sugar/operators/Comparator.h b/inst/include/Rcpp/sugar/operators/Comparator.h index d6446917a..f716ebe7e 100644 --- a/inst/include/Rcpp/sugar/operators/Comparator.h +++ b/inst/include/Rcpp/sugar/operators/Comparator.h @@ -35,7 +35,7 @@ class Comparator : typedef typename traits::storage_type::type STORAGE ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_), op() {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} inline int operator[]( R_xlen_t i ) const { STORAGE x = lhs[i] ; @@ -48,8 +48,8 @@ class Comparator : inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; Operator op ; } ; @@ -66,7 +66,7 @@ class Comparator : typedef typename traits::storage_type::type STORAGE ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_), op() {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} inline int operator[]( R_xlen_t i ) const { STORAGE y = rhs[i] ; @@ -77,8 +77,8 @@ class Comparator : inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; Operator op ; } ; @@ -94,7 +94,7 @@ class Comparator : typedef typename traits::storage_type::type STORAGE ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_), op() {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} inline int operator[]( R_xlen_t i ) const { return op( lhs[i], rhs[i] ) ; @@ -103,8 +103,8 @@ class Comparator : inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + typename Rcpp::traits::sugar_operand< LHS_TYPE >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_TYPE >::type rhs ; Operator op ; } ; diff --git a/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h b/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h index 7286fdeda..1ab11fc95 100644 --- a/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h +++ b/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h @@ -34,7 +34,7 @@ class Comparator_With_One_Value : public ::Rcpp::VectorBase< LGLSXP, true, Compa typedef int (Comparator_With_One_Value::*METHOD)(R_xlen_t) const ; Comparator_With_One_Value( const VEC_TYPE& lhs_, STORAGE rhs_ ) : - lhs(lhs_), rhs(rhs_), m(), op() { + lhs(lhs_.get_ref()), rhs(rhs_), m(), op() { m = Rcpp::traits::is_na(rhs) ? &Comparator_With_One_Value::rhs_is_na : @@ -49,7 +49,7 @@ class Comparator_With_One_Value : public ::Rcpp::VectorBase< LGLSXP, true, Compa inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_TYPE& lhs ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type lhs ; STORAGE rhs ; METHOD m ; Operator op ; @@ -73,7 +73,7 @@ class Comparator_With_One_Value : typedef int (Comparator_With_One_Value::*METHOD)(R_xlen_t) const ; Comparator_With_One_Value( const VEC_TYPE& lhs_, STORAGE rhs_ ) : - lhs(lhs_), rhs(rhs_), m(), op() { + lhs(lhs_.get_ref()), rhs(rhs_), m(), op() { m = Rcpp::traits::is_na(rhs) ? &Comparator_With_One_Value::rhs_is_na : @@ -88,7 +88,7 @@ class Comparator_With_One_Value : inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_TYPE& lhs ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type lhs ; STORAGE rhs ; METHOD m ; Operator op ; diff --git a/inst/include/Rcpp/sugar/operators/divides.h b/inst/include/Rcpp/sugar/operators/divides.h index 9485acf8b..add57ab29 100644 --- a/inst/include/Rcpp/sugar/operators/divides.h +++ b/inst/include/Rcpp/sugar/operators/divides.h @@ -47,8 +47,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -70,8 +70,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -96,8 +96,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -119,8 +119,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -145,8 +145,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -167,8 +167,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -192,8 +192,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE : REALSXP template @@ -215,8 +215,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -243,7 +243,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; } ; @@ -266,7 +266,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; double rhs ; } ; @@ -291,7 +291,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; } ; @@ -304,7 +304,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type VEC_EXT ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : - lhs(lhs_), rhs(rhs_){} + lhs(lhs_.get_ref()), rhs(rhs_){} inline double operator[]( R_xlen_t i ) const { return lhs[i] / rhs ; @@ -312,7 +312,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; double rhs ; } ; @@ -337,7 +337,7 @@ namespace sugar{ inline R_xlen_t size() const { return rhs.size() ; } private: STORAGE lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; bool lhs_na ; } ; // RTYPE = REALSXP @@ -357,7 +357,7 @@ namespace sugar{ inline R_xlen_t size() const { return rhs.size() ; } private: double lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; } ; @@ -381,7 +381,7 @@ namespace sugar{ private: STORAGE lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; bool lhs_na ; } ; // RTYPE = REALSXP @@ -402,7 +402,7 @@ namespace sugar{ private: double lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; } ; diff --git a/inst/include/Rcpp/sugar/operators/minus.h b/inst/include/Rcpp/sugar/operators/minus.h index 04bfcb7dc..1c2875c49 100644 --- a/inst/include/Rcpp/sugar/operators/minus.h +++ b/inst/include/Rcpp/sugar/operators/minus.h @@ -49,8 +49,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -72,8 +72,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -98,8 +98,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -121,8 +121,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -147,8 +147,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -170,8 +170,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -195,8 +195,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; template class Minus_Vector_Vector : @@ -217,8 +217,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -245,7 +245,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; } ; @@ -266,7 +266,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; double rhs ; } ; @@ -291,7 +291,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; } ; @@ -312,7 +312,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_EXT& lhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type lhs ; double rhs ; } ; @@ -340,7 +340,7 @@ namespace sugar{ private: STORAGE lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; bool lhs_na ; } ; template @@ -360,7 +360,7 @@ namespace sugar{ private: double lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; } ; @@ -385,7 +385,7 @@ namespace sugar{ private: STORAGE lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; bool lhs_na ; } ; @@ -407,7 +407,7 @@ namespace sugar{ private: double lhs ; - const VEC_EXT& rhs ; + typename Rcpp::traits::sugar_operand< VEC_EXT >::type rhs ; } ; diff --git a/inst/include/Rcpp/sugar/operators/not.h b/inst/include/Rcpp/sugar/operators/not.h index f5505aab6..940247d3d 100644 --- a/inst/include/Rcpp/sugar/operators/not.h +++ b/inst/include/Rcpp/sugar/operators/not.h @@ -80,7 +80,7 @@ namespace sugar{ typedef not_ OPERATOR ; Not_Vector( const VEC_TYPE& lhs_ ) : - lhs(lhs_), op() {} + lhs(lhs_.get_ref()), op() {} inline STORAGE operator[]( R_xlen_t i ) const { return op.apply( lhs[i] ) ; @@ -89,7 +89,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_TYPE& lhs ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type lhs ; OPERATOR op ; } ; diff --git a/inst/include/Rcpp/sugar/operators/plus.h b/inst/include/Rcpp/sugar/operators/plus.h index 9434f4853..1ef0e963e 100644 --- a/inst/include/Rcpp/sugar/operators/plus.h +++ b/inst/include/Rcpp/sugar/operators/plus.h @@ -49,8 +49,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // specialization of the above for REALSXP because : // NA_REAL + NA_REAL = NA_REAL @@ -76,8 +76,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -106,8 +106,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // LHS_NA = false & RTYPE = REALSXP template @@ -130,8 +130,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -159,8 +159,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RHS_NA = false, RTYPE = REALSXP template @@ -183,8 +183,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -211,8 +211,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // specialization for RHS_NA = false and LHS_NA = false, RTYPE = REALSXP template @@ -235,8 +235,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -266,7 +266,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; @@ -290,7 +290,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; @@ -314,7 +314,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; } ; @@ -337,7 +337,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; @@ -366,7 +366,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; } ; @@ -388,7 +388,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; @@ -413,7 +413,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; } ; @@ -435,7 +435,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; diff --git a/inst/include/Rcpp/sugar/operators/times.h b/inst/include/Rcpp/sugar/operators/times.h index 54dfe0449..5ac61b6e8 100644 --- a/inst/include/Rcpp/sugar/operators/times.h +++ b/inst/include/Rcpp/sugar/operators/times.h @@ -50,8 +50,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -75,8 +75,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -103,8 +103,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -127,8 +127,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -155,8 +155,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -179,8 +179,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // specialization for RHS_NA = false and LHS_NA = false @@ -204,8 +204,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; // RTYPE = REALSXP template @@ -228,8 +228,8 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const LHS_EXT& lhs ; - const RHS_EXT& rhs ; + typename Rcpp::traits::sugar_operand< LHS_EXT >::type lhs ; + typename Rcpp::traits::sugar_operand< RHS_EXT >::type rhs ; } ; @@ -254,7 +254,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; } ; @@ -277,7 +277,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; @@ -300,7 +300,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; bool rhs_na ; @@ -323,7 +323,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; @@ -352,7 +352,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; } ; @@ -375,7 +375,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; @@ -398,7 +398,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; STORAGE rhs ; } ; @@ -419,7 +419,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const EXT& lhs ; + typename Rcpp::traits::sugar_operand< EXT >::type lhs ; double rhs ; } ; diff --git a/inst/include/Rcpp/sugar/operators/unary_minus.h b/inst/include/Rcpp/sugar/operators/unary_minus.h index df6c075c9..2a06053d9 100644 --- a/inst/include/Rcpp/sugar/operators/unary_minus.h +++ b/inst/include/Rcpp/sugar/operators/unary_minus.h @@ -92,7 +92,7 @@ namespace sugar{ typedef unary_minus OPERATOR ; UnaryMinus_Vector( const VEC_TYPE& lhs_ ) : - lhs(lhs_), op() {} + lhs(lhs_.get_ref()), op() {} inline RESULT operator[]( R_xlen_t i ) const { return op.apply( lhs[i] ) ; @@ -101,7 +101,7 @@ namespace sugar{ inline R_xlen_t size() const { return lhs.size() ; } private: - const VEC_TYPE& lhs ; + typename Rcpp::traits::sugar_operand< VEC_TYPE >::type lhs ; OPERATOR op ; } ; diff --git a/inst/include/Rcpp/traits/sugar_operand.h b/inst/include/Rcpp/traits/sugar_operand.h new file mode 100644 index 000000000..e9e3802e3 --- /dev/null +++ b/inst/include/Rcpp/traits/sugar_operand.h @@ -0,0 +1,65 @@ +// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- +// +// sugar_operand.h: Rcpp R/C++ interface class library -- how sugar +// expressions hold their operands +// +// Copyright (C) 2026 Kevin Ushey +// +// 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 . + +#ifndef Rcpp__traits__sugar_operand_h +#define Rcpp__traits__sugar_operand_h + +namespace Rcpp{ +namespace traits{ + + // Objects with a storage policy (vectors, matrices, and classes derived + // from them) own an R object. + template + class _has_storage_policy_helper : __sfinae_types { + template static __one __test(typename U::Storage*); + template static __two __test(...); + public: + static const bool value = sizeof(__test(0)) == 1; + }; + + // Sugar expressions hold objects that own an R object by reference, but + // everything else (nested sugar expressions, and views such as + // MatrixColumn) by value. Those are usually temporaries, and holding + // them by reference leaves them dangling once the full-expression that + // created them ends, e.g. when an expression is stored in an `auto` + // variable. + template ::value> + struct sugar_operand { + typedef const T& type ; + } ; + + template + struct sugar_operand { + typedef const T type ; + } ; + + // Operands are often named by their CRTP base; hold the derived type. + template + struct sugar_operand< VectorBase, false > : sugar_operand {} ; + + template + struct sugar_operand< MatrixBase, false > : sugar_operand {} ; + +} // traits +} // Rcpp + +#endif diff --git a/inst/include/Rcpp/vector/MatrixBase.h b/inst/include/Rcpp/vector/MatrixBase.h index 13ce8dfce..880c55dbb 100644 --- a/inst/include/Rcpp/vector/MatrixBase.h +++ b/inst/include/Rcpp/vector/MatrixBase.h @@ -40,6 +40,10 @@ namespace Rcpp{ return static_cast(*this) ; } + const MATRIX& get_ref() const { + return static_cast(*this) ; + } + inline stored_type operator()( int i, int j) const { return static_cast(this)->operator()(i, j) ; } diff --git a/inst/include/RcppCommon.h b/inst/include/RcppCommon.h index ea23f5e82..3c199a157 100644 --- a/inst/include/RcppCommon.h +++ b/inst/include/RcppCommon.h @@ -172,6 +172,7 @@ namespace Rcpp { #include #include +#include #include #include diff --git a/inst/tinytest/cpp/sugar_expressions.cpp b/inst/tinytest/cpp/sugar_expressions.cpp new file mode 100644 index 000000000..c99e35b7a --- /dev/null +++ b/inst/tinytest/cpp/sugar_expressions.cpp @@ -0,0 +1,112 @@ +// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- +// +// sugar_expressions.cpp: Rcpp R/C++ interface class library -- sugar +// expression lifetime, aliasing, and operand length unit tests +// +// Copyright (C) 2026 Kevin Ushey +// +// 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 . + +#include +using namespace Rcpp; + +// Overwrite the stack where any destroyed temporaries used to live, so that +// an expression still referring to them reads garbage. +#if defined(__GNUC__) +__attribute__((noinline)) +#endif +void clobber_stack() { + volatile char buffer[16384]; + for (size_t i = 0; i < sizeof(buffer); i++) + buffer[i] = 0x7f; +} + +// [[Rcpp::export]] +NumericVector lifetime_arith(NumericVector x) { + auto e = x + x * 2.0; + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_unary(NumericVector x) { + auto e = -(x * 2.0); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_math(NumericVector x) { + auto e = sqrt(x * 4.0); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +LogicalVector lifetime_compare(NumericVector x) { + auto e = (x * 2.0) > (x + 1.0); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_ifelse(NumericVector x) { + auto e = ifelse(x > 1.0, x * 10.0, x * 0.0); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_rev(NumericVector x) { + auto e = rev(x * 2.0); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_rep_scalar() { + auto e = rep(2.5, 3); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_pmax(NumericVector x) { + auto e = pmax(x * 2.0, x + 1.0); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +double lifetime_sum(NumericVector x) { + auto e = sum(x * 2.0); + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_column(NumericMatrix m) { + auto e = m(_, 0) + 1.0; + clobber_stack(); + return e; +} + +// [[Rcpp::export]] +NumericVector lifetime_dnorm(NumericVector x) { + auto e = dnorm(x * 1.0, 0.0, 1.0); + clobber_stack(); + return e; +} diff --git a/inst/tinytest/test_sugar.R b/inst/tinytest/test_sugar.R index 1115dced7..2a0a3c723 100644 --- a/inst/tinytest/test_sugar.R +++ b/inst/tinytest/test_sugar.R @@ -22,6 +22,7 @@ if (Sys.getenv("RunAllRcppTests") != "yes") exit_file("Set 'RunAllRcppTests' to Rcpp::sourceCpp("cpp/sugar.cpp") Rcpp::sourceCpp("cpp/sugar_safe_math.cpp") Rcpp::sourceCpp("cpp/sugar_safe_math_fallback.cpp") +Rcpp::sourceCpp("cpp/sugar_expressions.cpp") ## There are some (documented, see https://blog.r-project.org/2020/11/02/will-r-work-on-apple-silicon/index.html) ## issues with NA propagation on arm64 / macOS. We not (yet ?) do anything special so we just skip some tests @@ -1704,3 +1705,21 @@ expect_equal(intmin(c(1:10)), 1L, info = "min(integer(...))") expect_equal(doublemin(1.0*c(1:10)), 1.0, info = "min(numeric(...))") expect_equal(intmax(c(1:10)), 10L, info = "min(integer(...))") expect_equal(doublemax(1.0*c(1:10)), 10.0, info = "min(numeric(...))") + + +## sugar expressions hold nested expressions by value, so they remain valid +## when stored (e.g. in an `auto` variable) past the full-expression that +## created them +x <- c(1, 2, 3) +expect_equal(lifetime_arith(x), x + x * 2, info = "auto: x + x * 2") +expect_equal(lifetime_unary(x), -(x * 2), info = "auto: -(x * 2)") +expect_equal(lifetime_math(x), sqrt(x * 4), info = "auto: sqrt(x * 4)") +expect_equal(lifetime_compare(x), (x * 2) > (x + 1), info = "auto: (x * 2) > (x + 1)") +expect_equal(lifetime_ifelse(x), ifelse(x > 1, x * 10, x * 0), info = "auto: ifelse()") +expect_equal(lifetime_rev(x), rev(x * 2), info = "auto: rev(x * 2)") +expect_equal(lifetime_rep_scalar(), rep(2.5, 3), info = "auto: rep(2.5, 3)") +expect_equal(lifetime_pmax(x), pmax(x * 2, x + 1), info = "auto: pmax()") +expect_equal(lifetime_sum(x), sum(x * 2), info = "auto: sum(x * 2)") +m <- matrix(c(1, 2, 3, 4, 5, 6), 3) +expect_equal(lifetime_column(m), m[, 1] + 1, info = "auto: m(_, 0) + 1") +expect_equal(lifetime_dnorm(x), dnorm(x), info = "auto: dnorm(x * 1)") From ecd157f43ac087c896865e3f70f5088f76e7304f Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 11:50:02 -0700 Subject: [PATCH 02/11] evaluate non-elementwise sugar before writing it in place Assigning a same-length sugar expression to a vector, or any expression to a range, matrix row or matrix column, writes into existing storage while the expression is still being read. When the expression read from that storage at other positions (e.g. `x = rev(x)`, `x[Range(1, n - 1)] = head(x, n - 1)`), the result was silently wrong. Elementwise nodes now declare themselves via a nested `rcpp_elementwise` type; those are still written in place, and everything else is evaluated into a temporary first. Part of #1512. --- inst/include/Rcpp/stats/dpq/dpq.h | 12 +++ inst/include/Rcpp/sugar/block/SugarBlock_1.h | 1 + inst/include/Rcpp/sugar/block/SugarBlock_2.h | 3 + inst/include/Rcpp/sugar/block/SugarBlock_3.h | 1 + inst/include/Rcpp/sugar/block/SugarMath.h | 3 + .../Rcpp/sugar/block/Vectorized_Math.h | 3 + inst/include/Rcpp/sugar/functions/clamp.h | 1 + inst/include/Rcpp/sugar/functions/complex.h | 1 + inst/include/Rcpp/sugar/functions/ifelse.h | 8 ++ inst/include/Rcpp/sugar/functions/is_finite.h | 2 + .../Rcpp/sugar/functions/is_infinite.h | 2 + inst/include/Rcpp/sugar/functions/is_na.h | 2 + inst/include/Rcpp/sugar/functions/is_nan.h | 2 + inst/include/Rcpp/sugar/functions/pmax.h | 2 + inst/include/Rcpp/sugar/functions/pmin.h | 2 + inst/include/Rcpp/sugar/functions/pow.h | 5 ++ inst/include/Rcpp/sugar/functions/rep.h | 2 + inst/include/Rcpp/sugar/functions/seq_along.h | 2 + inst/include/Rcpp/sugar/functions/sign.h | 1 + inst/include/Rcpp/sugar/logical/and.h | 4 + inst/include/Rcpp/sugar/logical/or.h | 4 + inst/include/Rcpp/sugar/nona/nona.h | 2 + .../include/Rcpp/sugar/operators/Comparator.h | 3 + .../operators/Comparator_With_One_Value.h | 2 + inst/include/Rcpp/sugar/operators/divides.h | 16 ++++ inst/include/Rcpp/sugar/operators/minus.h | 16 ++++ inst/include/Rcpp/sugar/operators/not.h | 1 + inst/include/Rcpp/sugar/operators/plus.h | 16 ++++ inst/include/Rcpp/sugar/operators/times.h | 16 ++++ .../Rcpp/sugar/operators/unary_minus.h | 1 + inst/include/Rcpp/traits/is_elementwise.h | 73 +++++++++++++++ inst/include/Rcpp/vector/MatrixColumn.h | 6 ++ inst/include/Rcpp/vector/MatrixRow.h | 6 ++ inst/include/Rcpp/vector/RangeIndexer.h | 6 ++ inst/include/Rcpp/vector/Vector.h | 11 ++- inst/include/RcppCommon.h | 1 + inst/tinytest/cpp/sugar_expressions.cpp | 89 +++++++++++++++++++ inst/tinytest/test_sugar.R | 31 +++++++ 38 files changed, 357 insertions(+), 2 deletions(-) create mode 100644 inst/include/Rcpp/traits/is_elementwise.h diff --git a/inst/include/Rcpp/stats/dpq/dpq.h b/inst/include/Rcpp/stats/dpq/dpq.h index 7aa7cff67..4e084b4a7 100644 --- a/inst/include/Rcpp/stats/dpq/dpq.h +++ b/inst/include/Rcpp/stats/dpq/dpq.h @@ -35,6 +35,7 @@ class D0 : public Rcpp::VectorBase< REALSXP, NA, D0 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; D0( FunPtr ptr_, const VEC_TYPE& vec_, bool log_ ) : ptr(ptr_), vec(vec_.get_ref()), log(log_) {} @@ -56,6 +57,7 @@ class D1 : public Rcpp::VectorBase< REALSXP, NA, D1 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; D1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_ , bool log_) : ptr(ptr_), vec(vec_.get_ref()), p0(p0_), log(log_) {} @@ -78,6 +80,7 @@ class D2 : public Rcpp::VectorBase< REALSXP, NA, D2 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; D2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_ , bool log_) : ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), log(log_) {} @@ -100,6 +103,7 @@ class D3 : public Rcpp::VectorBase< REALSXP, NA, D3 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,double,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; D3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_ , bool log_ ) : ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), p2(p2_), log(log_) {} @@ -125,6 +129,7 @@ class P0 : public Rcpp::VectorBase< REALSXP, NA, P0 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; P0( FunPtr ptr_, const VEC_TYPE& vec_, bool lower_tail = true, bool log_ = false ) : @@ -149,6 +154,7 @@ class P1 : public Rcpp::VectorBase< REALSXP, NA, P1 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; P1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, bool lower_tail = true, bool log_ = false ) : @@ -174,6 +180,7 @@ class P2 : public Rcpp::VectorBase< REALSXP, NA, P2 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; P2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, bool lower_tail = true, bool log_ = false ) : @@ -197,6 +204,7 @@ class P3 : public Rcpp::VectorBase< REALSXP, NA, P3 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; P3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_, bool lower_tail = true, bool log_ = false ) : @@ -223,6 +231,7 @@ class Q0 : public Rcpp::VectorBase< REALSXP, NA, Q0 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Q0( FunPtr ptr_, const VEC_TYPE& vec_, bool lower_tail = true, bool log_ = false ) : @@ -246,6 +255,7 @@ class Q1 : public Rcpp::VectorBase< REALSXP, NA, Q1 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Q1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, bool lower_tail = true, bool log_ = false ) : @@ -270,6 +280,7 @@ class Q2 : public Rcpp::VectorBase< REALSXP, NA, Q2 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Q2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, bool lower_tail = true, bool log_ = false ) : @@ -294,6 +305,7 @@ class Q3 : public Rcpp::VectorBase< REALSXP, NA, Q3 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,double,int,int) ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Q3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_, bool lower_tail = true, bool log_ = false ) : diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_1.h b/inst/include/Rcpp/sugar/block/SugarBlock_1.h index cbdbc0d2f..abe81d791 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_1.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_1.h @@ -29,6 +29,7 @@ template class SugarBlock_1 : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype , NA, SugarBlock_1 > { public: typedef RESULT_TYPE (*FunPtr)(U1) ; + typedef Rcpp::traits::is_elementwise< T1 > rcpp_elementwise ; SugarBlock_1( FunPtr ptr_, const T1 & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_2.h b/inst/include/Rcpp/sugar/block/SugarBlock_2.h index 603473c60..3576a6f7e 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_2.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_2.h @@ -29,6 +29,7 @@ template ::rtype , NA, SugarBlock_2 > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; + typedef Rcpp::traits::are_elementwise< T1, T2 > rcpp_elementwise ; SugarBlock_2( FunPtr ptr_, const T1 & x_, const T2& y_ ) : ptr(ptr_), x(x_.get_ref()), y(y_.get_ref()){ // TODO: check that x and y have same size @@ -50,6 +51,7 @@ template class SugarBlock_2__VP : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype , NA, SugarBlock_2__VP > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; + typedef Rcpp::traits::is_elementwise< T1 > rcpp_elementwise ; SugarBlock_2__VP( FunPtr ptr_, const T1 & x_, U2 u2 ) : ptr(ptr_), x(x_.get_ref()), y(u2){} @@ -68,6 +70,7 @@ template class SugarBlock_2__PV : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype , NA, SugarBlock_2__PV > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; + typedef Rcpp::traits::is_elementwise< T2 > rcpp_elementwise ; SugarBlock_2__PV( FunPtr ptr_, U1 u1, const T2& y_ ) : ptr(ptr_), x(u1), y(y_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_3.h b/inst/include/Rcpp/sugar/block/SugarBlock_3.h index 5fc46c74c..453436b89 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_3.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_3.h @@ -37,6 +37,7 @@ class SugarBlock_3_VVV : public Rcpp::VectorBase< SugarBlock_3_VVV > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2,U3) ; + typedef Rcpp::traits::are_elementwise< T1, T2, T3 > rcpp_elementwise ; SugarBlock_3_VVV( FunPtr ptr_, const T1 & x_, const T2& y_, const T3& z_ ) : ptr(ptr_), x(x_.get_ref()), y(y_.get_ref()), z(z_.get_ref()) { // TODO: size checks, recycling, etc ... diff --git a/inst/include/Rcpp/sugar/block/SugarMath.h b/inst/include/Rcpp/sugar/block/SugarMath.h index 4b0363c01..c32507777 100644 --- a/inst/include/Rcpp/sugar/block/SugarMath.h +++ b/inst/include/Rcpp/sugar/block/SugarMath.h @@ -34,6 +34,7 @@ class SugarMath_1 : public Rcpp::VectorBase< public: typedef Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype ,NA,T1> VEC_TYPE ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} @@ -57,6 +58,7 @@ class SugarMath_1 : public Rcpp::VectorBase< > { public: typedef Rcpp::VectorBase< INTSXP ,NA,T1> VEC_TYPE ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} @@ -81,6 +83,7 @@ Rcpp::VectorBase< > { public: typedef Rcpp::VectorBase< INTSXP ,false,T1> VEC_TYPE ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { diff --git a/inst/include/Rcpp/sugar/block/Vectorized_Math.h b/inst/include/Rcpp/sugar/block/Vectorized_Math.h index 798571bb4..1b4a0819f 100644 --- a/inst/include/Rcpp/sugar/block/Vectorized_Math.h +++ b/inst/include/Rcpp/sugar/block/Vectorized_Math.h @@ -32,6 +32,7 @@ class Vectorized : public VectorBase >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Vectorized( const VEC_TYPE& object_) : object( object_.get_ref() ){} inline double operator[]( R_xlen_t i) const { @@ -48,6 +49,7 @@ class Vectorized_INTSXP : public VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Vectorized_INTSXP( const VEC_TYPE& object_) : object( object_.get_ref() ){} inline double operator[]( R_xlen_t i) const { @@ -66,6 +68,7 @@ class Vectorized_INTSXP : public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Vectorized_INTSXP( const VEC_TYPE& object_) : object( object_.get_ref() ){} inline double operator[]( R_xlen_t i) const { diff --git a/inst/include/Rcpp/sugar/functions/clamp.h b/inst/include/Rcpp/sugar/functions/clamp.h index 868386ea3..70d5689da 100644 --- a/inst/include/Rcpp/sugar/functions/clamp.h +++ b/inst/include/Rcpp/sugar/functions/clamp.h @@ -62,6 +62,7 @@ class Clamp_Primitive_Vector_Primitive : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef clamp_operator OPERATOR ; + typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; Clamp_Primitive_Vector_Primitive( STORAGE lhs_, const T& vec_, STORAGE rhs_) : vec(vec_), op(lhs_,rhs_) {} diff --git a/inst/include/Rcpp/sugar/functions/complex.h b/inst/include/Rcpp/sugar/functions/complex.h index f897b5b87..76d99d6e8 100644 --- a/inst/include/Rcpp/sugar/functions/complex.h +++ b/inst/include/Rcpp/sugar/functions/complex.h @@ -35,6 +35,7 @@ class SugarComplex : public Rcpp::VectorBase< public: typedef Rcpp::VectorBase VEC_TYPE ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; SugarComplex( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/functions/ifelse.h b/inst/include/Rcpp/sugar/functions/ifelse.h index 340f79cb2..e8b52bd52 100644 --- a/inst/include/Rcpp/sugar/functions/ifelse.h +++ b/inst/include/Rcpp/sugar/functions/ifelse.h @@ -41,6 +41,7 @@ class IfElse : public VectorBase< typedef Rcpp::VectorBase LHS_TYPE ; typedef Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; + typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_T, RHS_T > rcpp_elementwise ; // typedef typename Rcpp::traits::Extractor::type LHS_EXT ; // typedef typename Rcpp::traits::Extractor::type RHS_EXT ; @@ -87,6 +88,7 @@ class IfElse : public VectorBase< typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_EXT, RHS_EXT > rcpp_elementwise ; IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -127,6 +129,7 @@ class IfElse_Primitive_Vector : public VectorBase< typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< COND_TYPE, RHS_EXT > rcpp_elementwise ; IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { @@ -164,6 +167,7 @@ class IfElse_Primitive_Vector : public VectorBa typedef Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< COND_TYPE, RHS_EXT > rcpp_elementwise ; IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { @@ -203,6 +207,7 @@ class IfElse_Vector_Primitive : public VectorBase< typedef Rcpp::VectorBase LHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; + typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_EXT > rcpp_elementwise ; IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { @@ -240,6 +245,7 @@ class IfElse_Vector_Primitive : public VectorBa typedef Rcpp::VectorBase LHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; + typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_EXT > rcpp_elementwise ; IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { @@ -278,6 +284,7 @@ class IfElse_Primitive_Primitive : public VectorBase< public: typedef Rcpp::VectorBase COND_TYPE ; typedef typename traits::storage_type::type STORAGE ; + typedef Rcpp::traits::is_elementwise< COND_TYPE > rcpp_elementwise ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { @@ -311,6 +318,7 @@ class IfElse_Primitive_Primitive : public VectorBase< public: typedef Rcpp::VectorBase COND_TYPE ; typedef typename traits::storage_type::type STORAGE ; + typedef Rcpp::traits::is_elementwise< COND_TYPE > rcpp_elementwise ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { diff --git a/inst/include/Rcpp/sugar/functions/is_finite.h b/inst/include/Rcpp/sugar/functions/is_finite.h index 9ed8cf332..059478132 100644 --- a/inst/include/Rcpp/sugar/functions/is_finite.h +++ b/inst/include/Rcpp/sugar/functions/is_finite.h @@ -29,6 +29,8 @@ template class IsFinite : public ::Rcpp::VectorBase< LGLSXP, false, IsFinite > { public: + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + IsFinite( const VEC_TYPE& obj_) : obj(obj_){} inline int operator[]( R_xlen_t i ) const { diff --git a/inst/include/Rcpp/sugar/functions/is_infinite.h b/inst/include/Rcpp/sugar/functions/is_infinite.h index 43ffd71e1..c1703ef67 100644 --- a/inst/include/Rcpp/sugar/functions/is_infinite.h +++ b/inst/include/Rcpp/sugar/functions/is_infinite.h @@ -29,6 +29,8 @@ template class IsInfinite : public ::Rcpp::VectorBase< LGLSXP, false, IsInfinite > { public: + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + IsInfinite( const VEC_TYPE& obj_) : obj(obj_){} inline int operator[]( R_xlen_t i ) const { diff --git a/inst/include/Rcpp/sugar/functions/is_na.h b/inst/include/Rcpp/sugar/functions/is_na.h index 345cff359..41b200b3a 100644 --- a/inst/include/Rcpp/sugar/functions/is_na.h +++ b/inst/include/Rcpp/sugar/functions/is_na.h @@ -31,6 +31,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsNa > public: typedef typename traits::storage_type::type STORAGE ; typedef Rcpp::VectorBase BASE ; + typedef Rcpp::traits::is_elementwise< BASE > rcpp_elementwise ; IsNa( const BASE& obj_) : obj(obj_.get_ref()){} @@ -53,6 +54,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsN public: typedef typename traits::storage_type::type STORAGE ; typedef Rcpp::VectorBase BASE ; + typedef Rcpp::traits::is_elementwise< BASE > rcpp_elementwise ; IsNa( const BASE& obj_) : obj(obj_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/functions/is_nan.h b/inst/include/Rcpp/sugar/functions/is_nan.h index a5dfb1e1e..82f60320b 100644 --- a/inst/include/Rcpp/sugar/functions/is_nan.h +++ b/inst/include/Rcpp/sugar/functions/is_nan.h @@ -29,6 +29,8 @@ template class IsNaN : public ::Rcpp::VectorBase< LGLSXP, false, IsNaN > { public: + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + IsNaN( const VEC_TYPE& obj_) : obj(obj_){} inline int operator[]( R_xlen_t i ) const { diff --git a/inst/include/Rcpp/sugar/functions/pmax.h b/inst/include/Rcpp/sugar/functions/pmax.h index 775ee7555..c25aa73b1 100644 --- a/inst/include/Rcpp/sugar/functions/pmax.h +++ b/inst/include/Rcpp/sugar/functions/pmax.h @@ -104,6 +104,7 @@ class Pmax_Vector_Vector : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmax_op OPERATOR ; + typedef Rcpp::traits::are_elementwise< LHS_T, RHS_T > rcpp_elementwise ; Pmax_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() {} @@ -132,6 +133,7 @@ class Pmax_Vector_Primitive : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmax_op_Vector_Primitive OPERATOR ; + typedef Rcpp::traits::is_elementwise< LHS_T > rcpp_elementwise ; Pmax_Vector_Primitive( const LHS_T& lhs_, STORAGE rhs_ ) : lhs(lhs_), op(rhs_) {} diff --git a/inst/include/Rcpp/sugar/functions/pmin.h b/inst/include/Rcpp/sugar/functions/pmin.h index 78e94abf7..533c8fc08 100644 --- a/inst/include/Rcpp/sugar/functions/pmin.h +++ b/inst/include/Rcpp/sugar/functions/pmin.h @@ -104,6 +104,7 @@ class Pmin_Vector_Vector : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmin_op OPERATOR ; + typedef Rcpp::traits::are_elementwise< LHS_T, RHS_T > rcpp_elementwise ; Pmin_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() {} @@ -132,6 +133,7 @@ class Pmin_Vector_Primitive : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmin_op_Vector_Primitive OPERATOR ; + typedef Rcpp::traits::is_elementwise< LHS_T > rcpp_elementwise ; Pmin_Vector_Primitive( const LHS_T& lhs_, STORAGE rhs_ ) : lhs(lhs_), op(rhs_) {} diff --git a/inst/include/Rcpp/sugar/functions/pow.h b/inst/include/Rcpp/sugar/functions/pow.h index 38204726c..ed4ca438a 100644 --- a/inst/include/Rcpp/sugar/functions/pow.h +++ b/inst/include/Rcpp/sugar/functions/pow.h @@ -29,6 +29,7 @@ template class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow > { public: typedef typename Rcpp::traits::storage_type::type STORAGE ; + typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; Pow( const T& object_, EXPONENT_TYPE exponent ) : object(object_), op(exponent) {} @@ -45,6 +46,8 @@ class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow template class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow > { public: + typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; + Pow( const T& object_, EXPONENT_TYPE exponent ) : object(object_), op(exponent) {} inline double operator[]( R_xlen_t i ) const { @@ -60,6 +63,8 @@ class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow template class Pow : public Rcpp::VectorBase< REALSXP ,false, Pow > { public: + typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; + Pow( const T& object_, EXPONENT_TYPE exponent ) : object(object_), op(exponent) {} inline double operator[]( R_xlen_t i ) const { diff --git a/inst/include/Rcpp/sugar/functions/rep.h b/inst/include/Rcpp/sugar/functions/rep.h index 4b3445bd7..adc389020 100644 --- a/inst/include/Rcpp/sugar/functions/rep.h +++ b/inst/include/Rcpp/sugar/functions/rep.h @@ -51,6 +51,8 @@ class Rep_Single : public Rcpp::VectorBase< Rep_Single > { public: + typedef Rcpp::traits::true_type rcpp_elementwise ; + Rep_Single( const T& x_, R_xlen_t n_) : x(x_), n(n_){} inline T operator[]( R_xlen_t ) const { diff --git a/inst/include/Rcpp/sugar/functions/seq_along.h b/inst/include/Rcpp/sugar/functions/seq_along.h index 247e9af2c..88e09cfd3 100644 --- a/inst/include/Rcpp/sugar/functions/seq_along.h +++ b/inst/include/Rcpp/sugar/functions/seq_along.h @@ -28,6 +28,8 @@ namespace sugar{ class SeqLen : public VectorBase< INTSXP,false,SeqLen > { public: + typedef Rcpp::traits::true_type rcpp_elementwise ; + SeqLen( R_xlen_t len_ ) : len(len_){} inline int operator[]( R_xlen_t i ) const { diff --git a/inst/include/Rcpp/sugar/functions/sign.h b/inst/include/Rcpp/sugar/functions/sign.h index 86273bbb8..4f0cc41ff 100644 --- a/inst/include/Rcpp/sugar/functions/sign.h +++ b/inst/include/Rcpp/sugar/functions/sign.h @@ -50,6 +50,7 @@ class Sign : public Rcpp::VectorBase< INTSXP,NA, Sign > { typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef int r_import_type ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Sign( const VEC_TYPE& object_ ) : object(object_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/logical/and.h b/inst/include/Rcpp/sugar/logical/and.h index 7738af424..881f9a821 100644 --- a/inst/include/Rcpp/sugar/logical/and.h +++ b/inst/include/Rcpp/sugar/logical/and.h @@ -206,6 +206,7 @@ class And_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -226,6 +227,7 @@ class And_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -246,6 +248,7 @@ class And_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -266,6 +269,7 @@ class And_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/logical/or.h b/inst/include/Rcpp/sugar/logical/or.h index 9ba1d2748..f5030cfcc 100644 --- a/inst/include/Rcpp/sugar/logical/or.h +++ b/inst/include/Rcpp/sugar/logical/or.h @@ -203,6 +203,7 @@ class Or_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -223,6 +224,7 @@ class Or_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -243,6 +245,7 @@ class Or_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -263,6 +266,7 @@ class Or_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/nona/nona.h b/inst/include/Rcpp/sugar/nona/nona.h index 865b876b8..3764bdd3a 100644 --- a/inst/include/Rcpp/sugar/nona/nona.h +++ b/inst/include/Rcpp/sugar/nona/nona.h @@ -30,6 +30,7 @@ namespace sugar { public: typedef typename Rcpp::VectorBase SUGAR_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; + typedef Rcpp::traits::is_elementwise< VECTOR > rcpp_elementwise ; Nona( const SUGAR_TYPE& expr) : data(expr.get_ref()){} @@ -47,6 +48,7 @@ namespace sugar { typedef typename Rcpp::VectorBase > SUGAR_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef typename Rcpp::Vector::const_iterator iterator ; + typedef Rcpp::traits::true_type rcpp_elementwise ; Nona( const SUGAR_TYPE& expr) : data(expr.get_ref().begin()), n(expr.size()){} diff --git a/inst/include/Rcpp/sugar/operators/Comparator.h b/inst/include/Rcpp/sugar/operators/Comparator.h index f716ebe7e..fc6dce1d1 100644 --- a/inst/include/Rcpp/sugar/operators/Comparator.h +++ b/inst/include/Rcpp/sugar/operators/Comparator.h @@ -33,6 +33,7 @@ class Comparator : typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} @@ -64,6 +65,7 @@ class Comparator : typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} @@ -92,6 +94,7 @@ class Comparator : typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; + typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} diff --git a/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h b/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h index 1ab11fc95..4c8a7c525 100644 --- a/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h +++ b/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h @@ -32,6 +32,7 @@ class Comparator_With_One_Value : public ::Rcpp::VectorBase< LGLSXP, true, Compa typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef int (Comparator_With_One_Value::*METHOD)(R_xlen_t) const ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Comparator_With_One_Value( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), m(), op() { @@ -71,6 +72,7 @@ class Comparator_With_One_Value : typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef int (Comparator_With_One_Value::*METHOD)(R_xlen_t) const ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Comparator_With_One_Value( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), m(), op() { diff --git a/inst/include/Rcpp/sugar/operators/divides.h b/inst/include/Rcpp/sugar/operators/divides.h index add57ab29..e4990cc57 100644 --- a/inst/include/Rcpp/sugar/operators/divides.h +++ b/inst/include/Rcpp/sugar/operators/divides.h @@ -33,6 +33,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -59,6 +60,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -83,6 +85,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -108,6 +111,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -133,6 +137,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -157,6 +162,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -181,6 +187,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -204,6 +211,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -229,6 +237,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) { @@ -254,6 +263,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) { @@ -279,6 +289,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -302,6 +313,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_){} @@ -325,6 +337,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; typedef typename traits::storage_type::type STORAGE ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -347,6 +360,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()) {} @@ -369,6 +383,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -391,6 +406,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()) {} diff --git a/inst/include/Rcpp/sugar/operators/minus.h b/inst/include/Rcpp/sugar/operators/minus.h index 1c2875c49..21802bbbd 100644 --- a/inst/include/Rcpp/sugar/operators/minus.h +++ b/inst/include/Rcpp/sugar/operators/minus.h @@ -35,6 +35,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -61,6 +62,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -85,6 +87,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -110,6 +113,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -134,6 +138,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -159,6 +164,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -184,6 +190,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -206,6 +213,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -232,6 +240,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -255,6 +264,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_){} @@ -278,6 +288,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -301,6 +312,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_){} @@ -328,6 +340,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -349,6 +362,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()){} @@ -372,6 +386,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -395,6 +410,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; + typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/operators/not.h b/inst/include/Rcpp/sugar/operators/not.h index 940247d3d..e8989d731 100644 --- a/inst/include/Rcpp/sugar/operators/not.h +++ b/inst/include/Rcpp/sugar/operators/not.h @@ -78,6 +78,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef not_ OPERATOR ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; Not_Vector( const VEC_TYPE& lhs_ ) : lhs(lhs_.get_ref()), op() {} diff --git a/inst/include/Rcpp/sugar/operators/plus.h b/inst/include/Rcpp/sugar/operators/plus.h index 1ef0e963e..d6549e8d9 100644 --- a/inst/include/Rcpp/sugar/operators/plus.h +++ b/inst/include/Rcpp/sugar/operators/plus.h @@ -35,6 +35,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -65,6 +66,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} @@ -93,6 +95,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -119,6 +122,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -146,6 +150,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -172,6 +177,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -200,6 +206,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -224,6 +231,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -252,6 +260,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) @@ -278,6 +287,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor< REALSXP, NA, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -303,6 +313,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -326,6 +337,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor< REALSXP, false, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -353,6 +365,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -376,6 +389,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -402,6 +416,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -424,6 +439,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor< REALSXP, false, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} diff --git a/inst/include/Rcpp/sugar/operators/times.h b/inst/include/Rcpp/sugar/operators/times.h index 5ac61b6e8..71206d270 100644 --- a/inst/include/Rcpp/sugar/operators/times.h +++ b/inst/include/Rcpp/sugar/operators/times.h @@ -35,6 +35,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -63,6 +64,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -90,6 +92,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -116,6 +119,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -142,6 +146,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -168,6 +173,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -193,6 +199,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -217,6 +224,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; + typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} @@ -240,6 +248,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) @@ -265,6 +274,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -289,6 +299,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -312,6 +323,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -339,6 +351,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -363,6 +376,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -387,6 +401,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -408,6 +423,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; + typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} diff --git a/inst/include/Rcpp/sugar/operators/unary_minus.h b/inst/include/Rcpp/sugar/operators/unary_minus.h index 2a06053d9..911d3cd9d 100644 --- a/inst/include/Rcpp/sugar/operators/unary_minus.h +++ b/inst/include/Rcpp/sugar/operators/unary_minus.h @@ -90,6 +90,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename unary_minus_result_type::type RESULT ; typedef unary_minus OPERATOR ; + typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; UnaryMinus_Vector( const VEC_TYPE& lhs_ ) : lhs(lhs_.get_ref()), op() {} diff --git a/inst/include/Rcpp/traits/is_elementwise.h b/inst/include/Rcpp/traits/is_elementwise.h new file mode 100644 index 000000000..9ddcfa95b --- /dev/null +++ b/inst/include/Rcpp/traits/is_elementwise.h @@ -0,0 +1,73 @@ +// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- +// +// is_elementwise.h: Rcpp R/C++ interface class library -- whether a sugar +// expression can be written into one of its own operands in place +// +// Copyright (C) 2026 Kevin Ushey +// +// 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 . + +#ifndef Rcpp__traits__is_elementwise_h +#define Rcpp__traits__is_elementwise_h + +namespace Rcpp{ +namespace traits{ + + template + class _has_elementwise_marker_helper : __sfinae_types { + template static __one __test(typename U::rcpp_elementwise*); + template static __two __test(...); + public: + static const bool value = sizeof(__test(0)) == 1; + }; + + // An expression is elementwise when its element i depends only on + // element i of the vectors it reads, all of which have the expression's + // length. Writing such an expression into one of those vectors (or a + // view of one) in place is safe; anything else has to be evaluated into + // a temporary first. + // + // Vectors and matrices are elementwise; sugar expressions opt in with a + // nested `rcpp_elementwise` type (usually defined in terms of their + // operands), and are assumed not to be elementwise otherwise. + template < + typename T, + bool = _has_storage_policy_helper::value, + bool = _has_elementwise_marker_helper::value + > + struct is_elementwise : false_type {} ; + + template + struct is_elementwise : true_type {} ; + + template + struct is_elementwise : + integral_constant {} ; + + template + struct is_elementwise< VectorBase, false, false > : is_elementwise {} ; + + template + struct are_elementwise : integral_constant::value && + is_elementwise::value && + is_elementwise::value + > {} ; + +} // traits +} // Rcpp + +#endif diff --git a/inst/include/Rcpp/vector/MatrixColumn.h b/inst/include/Rcpp/vector/MatrixColumn.h index ffd81721c..6087f842f 100644 --- a/inst/include/Rcpp/vector/MatrixColumn.h +++ b/inst/include/Rcpp/vector/MatrixColumn.h @@ -66,6 +66,12 @@ class MatrixColumn : public VectorBase > { template MatrixColumn& operator=( const Rcpp::VectorBase& rhs ){ + if( ! traits::is_elementwise::value ){ + // rhs may read from this column's matrix, so evaluate it first + const Vector tmp(rhs) ; + return operator=( tmp ) ; + } + const T& ref = rhs.get_ref() ; RCPP_LOOP_UNROLL(start,ref) return *this ; diff --git a/inst/include/Rcpp/vector/MatrixRow.h b/inst/include/Rcpp/vector/MatrixRow.h index 2a5945c16..6266eef4b 100644 --- a/inst/include/Rcpp/vector/MatrixRow.h +++ b/inst/include/Rcpp/vector/MatrixRow.h @@ -153,6 +153,12 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow > { template MatrixRow& operator=( const Rcpp::VectorBase& rhs ){ + if( ! traits::is_elementwise::value ){ + // rhs may read from this row's matrix, so evaluate it first + const Vector tmp(rhs) ; + return operator=( tmp ) ; + } + int n = size() ; const T& ref = rhs.get_ref() ; RCPP_LOOP_UNROLL_LHSFUN(start,get_parent_index,ref) diff --git a/inst/include/Rcpp/vector/RangeIndexer.h b/inst/include/Rcpp/vector/RangeIndexer.h index e67600b3e..1c4edf629 100644 --- a/inst/include/Rcpp/vector/RangeIndexer.h +++ b/inst/include/Rcpp/vector/RangeIndexer.h @@ -24,6 +24,12 @@ #define Rcpp__vector__RangeIndexer_h #define UNROLL_LOOP(OP) \ + if( ! ::Rcpp::traits::is_elementwise::value ){ \ + /* x may read from the vector this range */ \ + /* indexes, so evaluate it first */ \ + const Vector tmp(x) ; \ + return operator OP ( tmp ) ; \ + } \ typedef typename ::Rcpp::traits::Extractor::type EXT ; \ const EXT& input( x.get_ref() ) ; \ R_xlen_t __trip_count = (size_) >> 2; \ diff --git a/inst/include/Rcpp/vector/Vector.h b/inst/include/Rcpp/vector/Vector.h index bfb78106c..751cf4d82 100644 --- a/inst/include/Rcpp/vector/Vector.h +++ b/inst/include/Rcpp/vector/Vector.h @@ -1051,8 +1051,15 @@ class Vector : inline void assign_sugar_expression( const T& x ) { R_xlen_t n = size() ; if( n == x.size() ){ - // just copy the data - import_expression(x, n ) ; + // write into the existing storage; an expression that isn't + // elementwise may read from this vector (e.g. `x = rev(x)`), so + // evaluate it first + if( traits::is_elementwise::value ){ + import_expression(x, n ) ; + } else { + const Vector< T::r_type::value > tmp(x) ; + import_expression< Vector< T::r_type::value > >(tmp, n ) ; + } } else{ // different size, so we change the memory Shield wrapped(wrap(x)); diff --git a/inst/include/RcppCommon.h b/inst/include/RcppCommon.h index 3c199a157..996fad61b 100644 --- a/inst/include/RcppCommon.h +++ b/inst/include/RcppCommon.h @@ -173,6 +173,7 @@ namespace Rcpp { #include #include #include +#include #include #include diff --git a/inst/tinytest/cpp/sugar_expressions.cpp b/inst/tinytest/cpp/sugar_expressions.cpp index c99e35b7a..4b0e3ef75 100644 --- a/inst/tinytest/cpp/sugar_expressions.cpp +++ b/inst/tinytest/cpp/sugar_expressions.cpp @@ -110,3 +110,92 @@ NumericVector lifetime_dnorm(NumericVector x) { clobber_stack(); return e; } + +// [[Rcpp::export]] +NumericVector alias_rev(NumericVector x) { + x = rev(x); + return x; +} + +// [[Rcpp::export]] +NumericVector alias_rev_copy(NumericVector x) { + NumericVector y = x; + y = rev(x); + return y; +} + +// [[Rcpp::export]] +NumericVector alias_mixed(NumericVector x) { + x = x + rev(x); + return x; +} + +// [[Rcpp::export]] +NumericVector alias_sapply(NumericVector x) { + x = sapply(x, [&](double v) { return v - x[0]; }); + return x; +} + +// [[Rcpp::export]] +NumericVector alias_elementwise(NumericVector x) { + x = x * 2.0 + x; + return x; +} + +// [[Rcpp::export]] +NumericVector alias_range_shift(NumericVector x) { + R_xlen_t n = x.size(); + x[Range(1, n - 1)] = head(x, n - 1); + return x; +} + +// [[Rcpp::export]] +NumericVector alias_range_rev(NumericVector x) { + R_xlen_t n = x.size(); + x[Range(0, n - 1)] = rev(x); + return x; +} + +// [[Rcpp::export]] +NumericVector alias_range_add_rev(NumericVector x) { + R_xlen_t n = x.size(); + x[Range(0, n - 1)] += rev(x); + return x; +} + +// [[Rcpp::export]] +NumericMatrix alias_column_rev(NumericMatrix m) { + m(_, 0) = rev(m(_, 0)); + return m; +} + +// [[Rcpp::export]] +NumericMatrix alias_row_rev(NumericMatrix m) { + m(0, _) = rev(m(0, _)); + return m; +} + +// [[Rcpp::export]] +LogicalVector elementwise_flags(NumericVector x, NumericMatrix m) { + // copy into locals, since binding the static `value` members by + // reference would require them to have definitions + bool vector = traits::is_elementwise::value; + bool arith = traits::is_elementwise::value; + bool math = traits::is_elementwise::value; + bool if_else = traits::is_elementwise 0.0, x, -x))>::value; + bool reversed = traits::is_elementwise::value; + bool arith_rev = traits::is_elementwise::value; + bool first = traits::is_elementwise::value; + bool column = traits::is_elementwise::value; + + return LogicalVector::create( + _["vector"] = vector, + _["arith"] = arith, + _["math"] = math, + _["ifelse"] = if_else, + _["rev"] = reversed, + _["arith_rev"] = arith_rev, + _["head"] = first, + _["column"] = column + ); +} diff --git a/inst/tinytest/test_sugar.R b/inst/tinytest/test_sugar.R index 2a0a3c723..5054d40bf 100644 --- a/inst/tinytest/test_sugar.R +++ b/inst/tinytest/test_sugar.R @@ -1723,3 +1723,34 @@ expect_equal(lifetime_sum(x), sum(x * 2), info = "auto: sum(x * 2)") m <- matrix(c(1, 2, 3, 4, 5, 6), 3) expect_equal(lifetime_column(m), m[, 1] + 1, info = "auto: m(_, 0) + 1") expect_equal(lifetime_dnorm(x), dnorm(x), info = "auto: dnorm(x * 1)") + +## same-length assignment writes into the existing storage, so an expression +## that reads from the target has to be evaluated before it is written. The +## writes also modify the argument itself, hence the fresh copies. +x <- function() c(1, 2, 3, 4, 5) +expect_equal(alias_rev(x()), rev(x()), info = "x = rev(x)") +expect_equal(alias_rev_copy(x()), rev(x()), info = "y = x; y = rev(x)") +expect_equal(alias_mixed(x()), x() + rev(x()), info = "x = x + rev(x)") +expect_equal(alias_sapply(x()), x() - x()[1], info = "x = sapply(x, )") +expect_equal(alias_elementwise(x()), x() * 2 + x(), info = "x = x * 2 + x") +expect_equal(alias_range_shift(x()), c(1, 1, 2, 3, 4), info = "x[1:n-1] = head(x, n-1)") +expect_equal(alias_range_rev(x()), rev(x()), info = "x[0:n-1] = rev(x)") +expect_equal(alias_range_add_rev(x()), x() + rev(x()), info = "x[0:n-1] += rev(x)") +m <- function() matrix(c(1, 2, 3, 4, 5, 6), 3) +expect_equal(alias_column_rev(m())[, 1], rev(m()[, 1]), info = "m(_, 0) = rev(m(_, 0))") +m <- function() matrix(c(1, 2, 3, 4, 5, 6), 2) +expect_equal(alias_row_rev(m())[1, ], rev(m()[1, ]), info = "m(0, _) = rev(m(0, _))") + +## assignment still happens in place, keeping attributes +x <- function() c(a = 1, b = 2, c = 3) +expect_equal(names(alias_rev(x())), names(x()), info = "x = rev(x) keeps names") +expect_equal(names(alias_elementwise(x())), names(x()), info = "x = x * 2 + x keeps names") + +## only vectors and elementwise expressions over them are written in place +flags <- elementwise_flags(c(1, 2, 3), matrix(1, 2, 2)) +expect_equal( + flags, + c(vector = TRUE, arith = TRUE, math = TRUE, ifelse = TRUE, + rev = FALSE, arith_rev = FALSE, head = FALSE, column = FALSE), + info = "traits::is_elementwise" +) From dd71cd583132be5c8a71bdb174b55556d8b28684 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 11:58:26 -0700 Subject: [PATCH 03/11] check that sugar operands have matching lengths Sugar operations on two or more vectors took their length from one operand and never compared it with the others, so a shorter operand was read past its end and a longer one was silently truncated. Likewise for vectors assigned into a range, matrix row or matrix column. These now signal an error, matching the documented requirement that operands have the same size. Part of #1512. --- inst/include/Rcpp/sugar/block/SugarBlock_2.h | 2 +- inst/include/Rcpp/sugar/block/SugarBlock_3.h | 2 +- inst/include/Rcpp/sugar/functions/ifelse.h | 12 ++--- .../Rcpp/sugar/functions/mapply/mapply_2.h | 4 +- .../Rcpp/sugar/functions/mapply/mapply_3.h | 4 +- inst/include/Rcpp/sugar/functions/pmax.h | 4 +- inst/include/Rcpp/sugar/functions/pmin.h | 4 +- inst/include/Rcpp/sugar/logical/and.h | 16 ++++-- inst/include/Rcpp/sugar/logical/or.h | 16 ++++-- .../include/Rcpp/sugar/operators/Comparator.h | 12 +++-- inst/include/Rcpp/sugar/operators/divides.h | 32 +++++++++--- inst/include/Rcpp/sugar/operators/minus.h | 32 +++++++++--- inst/include/Rcpp/sugar/operators/plus.h | 32 +++++++++--- inst/include/Rcpp/sugar/operators/times.h | 26 +++++++--- inst/include/Rcpp/sugar/sugar_forward.h | 3 ++ inst/include/Rcpp/sugar/tools/check_sizes.h | 50 +++++++++++++++++++ inst/include/Rcpp/vector/MatrixColumn.h | 4 ++ inst/include/Rcpp/vector/MatrixRow.h | 4 ++ inst/include/Rcpp/vector/RangeIndexer.h | 1 + inst/tinytest/cpp/sugar_expressions.cpp | 48 ++++++++++++++++++ inst/tinytest/test_sugar.R | 18 +++++++ 21 files changed, 273 insertions(+), 53 deletions(-) create mode 100644 inst/include/Rcpp/sugar/tools/check_sizes.h diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_2.h b/inst/include/Rcpp/sugar/block/SugarBlock_2.h index 3576a6f7e..88aa65475 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_2.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_2.h @@ -32,7 +32,7 @@ class SugarBlock_2 : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits rcpp_elementwise ; SugarBlock_2( FunPtr ptr_, const T1 & x_, const T2& y_ ) : ptr(ptr_), x(x_.get_ref()), y(y_.get_ref()){ - // TODO: check that x and y have same size + check_sizes(x.size(), y.size()) ; } inline RESULT_TYPE operator[]( R_xlen_t i) const { diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_3.h b/inst/include/Rcpp/sugar/block/SugarBlock_3.h index 453436b89..2f41a0fa6 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_3.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_3.h @@ -40,7 +40,7 @@ class SugarBlock_3_VVV : public Rcpp::VectorBase< typedef Rcpp::traits::are_elementwise< T1, T2, T3 > rcpp_elementwise ; SugarBlock_3_VVV( FunPtr ptr_, const T1 & x_, const T2& y_, const T3& z_ ) : ptr(ptr_), x(x_.get_ref()), y(y_.get_ref()), z(z_.get_ref()) { - // TODO: size checks, recycling, etc ... + check_sizes(x.size(), y.size(), z.size()) ; } inline RESULT_TYPE operator[]( R_xlen_t i) const { return ptr( x[i], y[i], z[i] ) ; diff --git a/inst/include/Rcpp/sugar/functions/ifelse.h b/inst/include/Rcpp/sugar/functions/ifelse.h index e8b52bd52..22f8090d7 100644 --- a/inst/include/Rcpp/sugar/functions/ifelse.h +++ b/inst/include/Rcpp/sugar/functions/ifelse.h @@ -48,7 +48,7 @@ class IfElse : public VectorBase< IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { - /* FIXME : cond, lhs and rhs must all have the same size */ + check_sizes(cond.size(), lhs.size(), rhs.size()) ; RCPP_DEBUG( DEMANGLE(IfElse) ) ; } @@ -92,7 +92,7 @@ class IfElse : public VectorBase< IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { - /* FIXME : cond, lhs and rhs must all have the same size */ + check_sizes(cond.size(), lhs.size(), rhs.size()) ; } inline STORAGE operator[]( R_xlen_t i ) const { @@ -133,7 +133,7 @@ class IfElse_Primitive_Vector : public VectorBase< IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { - /* FIXME : cond, lhs and rhs must all have the sale size */ + check_sizes(cond.size(), rhs.size()) ; } inline STORAGE operator[]( R_xlen_t i ) const { @@ -171,7 +171,7 @@ class IfElse_Primitive_Vector : public VectorBa IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { - /* FIXME : cond, lhs and rhs must all have the same size */ + check_sizes(cond.size(), rhs.size()) ; } inline STORAGE operator[]( R_xlen_t i ) const { @@ -211,7 +211,7 @@ class IfElse_Vector_Primitive : public VectorBase< IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { - /* FIXME : cond, lhs and rhs must all have the same size */ + check_sizes(cond.size(), lhs.size()) ; } inline STORAGE operator[]( R_xlen_t i ) const { @@ -249,7 +249,7 @@ class IfElse_Vector_Primitive : public VectorBa IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { - /* FIXME : cond, lhs and rhs must all have the sale size */ + check_sizes(cond.size(), lhs.size()) ; } inline STORAGE operator[]( R_xlen_t i ) const { diff --git a/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h b/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h index 89e040020..b8048f621 100644 --- a/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h +++ b/inst/include/Rcpp/sugar/functions/mapply/mapply_2.h @@ -42,7 +42,9 @@ class Mapply_2 : public VectorBase< typedef typename ::Rcpp::traits::result_of::type result_type ; Mapply_2( const T_1& vec_1_, const T_2& vec_2_, Function fun_ ) : - vec_1(vec_1_), vec_2(vec_2_), fun(fun_){} + vec_1(vec_1_), vec_2(vec_2_), fun(fun_){ + check_sizes(vec_1.size(), vec_2.size()) ; + } inline result_type operator[]( R_xlen_t i ) const { return fun( vec_1[i], vec_2[i] ); diff --git a/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h b/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h index cecfa3bfb..b03fbe0d8 100644 --- a/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h +++ b/inst/include/Rcpp/sugar/functions/mapply/mapply_3.h @@ -51,7 +51,9 @@ class Mapply_3 : public VectorBase< typedef typename Rcpp::traits::Extractor::type EXT_3 ; Mapply_3( const VEC_1& vec_1_, const VEC_2& vec_2_, const VEC_3& vec_3_, Function fun_ ) : - vec_1(vec_1_.get_ref()), vec_2(vec_2_.get_ref()), vec_3(vec_3_.get_ref()), fun(fun_){} + vec_1(vec_1_.get_ref()), vec_2(vec_2_.get_ref()), vec_3(vec_3_.get_ref()), fun(fun_){ + check_sizes(vec_1.size(), vec_2.size(), vec_3.size()) ; + } inline result_type operator[]( R_xlen_t i ) const { return fun( vec_1[i], vec_2[i], vec_3[i] ); diff --git a/inst/include/Rcpp/sugar/functions/pmax.h b/inst/include/Rcpp/sugar/functions/pmax.h index c25aa73b1..aeb00eea9 100644 --- a/inst/include/Rcpp/sugar/functions/pmax.h +++ b/inst/include/Rcpp/sugar/functions/pmax.h @@ -106,7 +106,9 @@ class Pmax_Vector_Vector : public VectorBase< typedef pmax_op OPERATOR ; typedef Rcpp::traits::are_elementwise< LHS_T, RHS_T > rcpp_elementwise ; - Pmax_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() {} + Pmax_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { return op( lhs[i], rhs[i] ) ; diff --git a/inst/include/Rcpp/sugar/functions/pmin.h b/inst/include/Rcpp/sugar/functions/pmin.h index 533c8fc08..696b6594d 100644 --- a/inst/include/Rcpp/sugar/functions/pmin.h +++ b/inst/include/Rcpp/sugar/functions/pmin.h @@ -106,7 +106,9 @@ class Pmin_Vector_Vector : public VectorBase< typedef pmin_op OPERATOR ; typedef Rcpp::traits::are_elementwise< LHS_T, RHS_T > rcpp_elementwise ; - Pmin_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() {} + Pmin_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { return op( lhs[i], rhs[i] ) ; diff --git a/inst/include/Rcpp/sugar/logical/and.h b/inst/include/Rcpp/sugar/logical/and.h index 881f9a821..e3ddb5cbf 100644 --- a/inst/include/Rcpp/sugar/logical/and.h +++ b/inst/include/Rcpp/sugar/logical/and.h @@ -208,7 +208,9 @@ class And_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; @@ -229,7 +231,9 @@ class And_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; @@ -250,7 +254,9 @@ class And_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; @@ -271,7 +277,9 @@ class And_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE && rhs[i] == TRUE ) return TRUE ; diff --git a/inst/include/Rcpp/sugar/logical/or.h b/inst/include/Rcpp/sugar/logical/or.h index f5030cfcc..1a2dd5823 100644 --- a/inst/include/Rcpp/sugar/logical/or.h +++ b/inst/include/Rcpp/sugar/logical/or.h @@ -205,7 +205,9 @@ class Or_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; @@ -226,7 +228,9 @@ class Or_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; @@ -247,7 +251,9 @@ class Or_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; @@ -268,7 +274,9 @@ class Or_LogicalExpression_LogicalExpression typedef typename Rcpp::VectorBase RHS_TYPE ; typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; - Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const{ if( lhs[i] == TRUE || rhs[i] == TRUE ) return TRUE ; diff --git a/inst/include/Rcpp/sugar/operators/Comparator.h b/inst/include/Rcpp/sugar/operators/Comparator.h index fc6dce1d1..4832dbb9f 100644 --- a/inst/include/Rcpp/sugar/operators/Comparator.h +++ b/inst/include/Rcpp/sugar/operators/Comparator.h @@ -36,7 +36,9 @@ class Comparator : typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() { + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const { STORAGE x = lhs[i] ; @@ -68,7 +70,9 @@ class Comparator : typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() { + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const { STORAGE y = rhs[i] ; @@ -97,7 +101,9 @@ class Comparator : typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() { + check_sizes(lhs.size(), rhs.size()) ; + } inline int operator[]( R_xlen_t i ) const { return op( lhs[i], rhs[i] ) ; diff --git a/inst/include/Rcpp/sugar/operators/divides.h b/inst/include/Rcpp/sugar/operators/divides.h index e4990cc57..b2ab1f42b 100644 --- a/inst/include/Rcpp/sugar/operators/divides.h +++ b/inst/include/Rcpp/sugar/operators/divides.h @@ -36,7 +36,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE x = lhs[i] ; @@ -63,7 +65,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] / rhs[i] ; @@ -88,7 +92,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE y = rhs[i] ; @@ -114,7 +120,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] / rhs[i] ; @@ -140,7 +148,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE x = lhs[i] ; @@ -165,7 +175,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] / rhs[i] ; @@ -190,7 +202,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { return lhs[i] / rhs[i] ; @@ -214,7 +228,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] / rhs[i] ; diff --git a/inst/include/Rcpp/sugar/operators/minus.h b/inst/include/Rcpp/sugar/operators/minus.h index 21802bbbd..68c7e3ace 100644 --- a/inst/include/Rcpp/sugar/operators/minus.h +++ b/inst/include/Rcpp/sugar/operators/minus.h @@ -38,7 +38,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE x = lhs[i] ; @@ -65,7 +67,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] - rhs[i] ; @@ -90,7 +94,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE y = rhs[i] ; @@ -116,7 +122,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] - rhs[i] ; @@ -141,7 +149,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE x = lhs[i] ; @@ -167,7 +177,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] - rhs[i] ; @@ -193,7 +205,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { return lhs[i] - rhs[i]; @@ -216,7 +230,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] - rhs[i] ; diff --git a/inst/include/Rcpp/sugar/operators/plus.h b/inst/include/Rcpp/sugar/operators/plus.h index d6549e8d9..b25817695 100644 --- a/inst/include/Rcpp/sugar/operators/plus.h +++ b/inst/include/Rcpp/sugar/operators/plus.h @@ -38,7 +38,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE lhs_ = lhs[i] ; @@ -69,7 +71,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] + rhs[i] ; @@ -98,7 +102,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE rhs_ = rhs[i] ; @@ -125,7 +131,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] + rhs[i] ; @@ -153,7 +161,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE lhs_ = lhs[i] ; @@ -180,7 +190,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] + rhs[i] ; @@ -209,7 +221,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { return lhs[i] + rhs[i]; @@ -234,7 +248,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] + rhs[i] ; diff --git a/inst/include/Rcpp/sugar/operators/times.h b/inst/include/Rcpp/sugar/operators/times.h index 71206d270..f59752d69 100644 --- a/inst/include/Rcpp/sugar/operators/times.h +++ b/inst/include/Rcpp/sugar/operators/times.h @@ -39,6 +39,7 @@ namespace sugar{ Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; } inline STORAGE operator[]( R_xlen_t i ) const { @@ -68,6 +69,7 @@ namespace sugar{ Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { + check_sizes(lhs.size(), rhs.size()) ; } inline double operator[]( R_xlen_t i ) const { @@ -95,7 +97,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE rhs_ = rhs[i] ; @@ -122,7 +126,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] * rhs[i] ; @@ -149,7 +155,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { STORAGE lhs_ = lhs[i] ; @@ -176,7 +184,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] * rhs[i] ; @@ -202,7 +212,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline STORAGE operator[]( R_xlen_t i ) const { return lhs[i] * rhs[i]; @@ -227,7 +239,9 @@ namespace sugar{ typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : - lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ + check_sizes(lhs.size(), rhs.size()) ; + } inline double operator[]( R_xlen_t i ) const { return lhs[i] * rhs[i] ; diff --git a/inst/include/Rcpp/sugar/sugar_forward.h b/inst/include/Rcpp/sugar/sugar_forward.h index bf78e6378..4981c4fbe 100644 --- a/inst/include/Rcpp/sugar/sugar_forward.h +++ b/inst/include/Rcpp/sugar/sugar_forward.h @@ -25,6 +25,9 @@ // traits #include +// tools +#include + // abstractions #include diff --git a/inst/include/Rcpp/sugar/tools/check_sizes.h b/inst/include/Rcpp/sugar/tools/check_sizes.h new file mode 100644 index 000000000..0978d6847 --- /dev/null +++ b/inst/include/Rcpp/sugar/tools/check_sizes.h @@ -0,0 +1,50 @@ +// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- +// +// check_sizes.h: Rcpp R/C++ interface class library -- operand length checks +// +// Copyright (C) 2026 Kevin Ushey +// +// 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 . + +#ifndef Rcpp__sugar__tools__check_sizes_h +#define Rcpp__sugar__tools__check_sizes_h + +namespace Rcpp{ +namespace sugar{ + + // Sugar doesn't recycle the way R does: the vectors an expression + // combines must all have the same length. + inline void check_sizes(R_xlen_t n1, R_xlen_t n2) { + if (n1 != n2) + stop("sugar operands have different lengths (%d and %d)", n1, n2); + } + + inline void check_sizes(R_xlen_t n1, R_xlen_t n2, R_xlen_t n3) { + if (n1 != n2 || n1 != n3) + stop("sugar operands have different lengths (%d, %d and %d)", n1, n2, n3); + } + + // Likewise, a vector assigned into a range, row or column must have the + // same length as that target. + inline void check_assign_size(R_xlen_t target, R_xlen_t value) { + if (target != value) + stop("cannot assign a vector of length %d to a target of length %d", value, target); + } + +} // sugar +} // Rcpp + +#endif diff --git a/inst/include/Rcpp/vector/MatrixColumn.h b/inst/include/Rcpp/vector/MatrixColumn.h index 6087f842f..9d997198e 100644 --- a/inst/include/Rcpp/vector/MatrixColumn.h +++ b/inst/include/Rcpp/vector/MatrixColumn.h @@ -66,6 +66,8 @@ class MatrixColumn : public VectorBase > { template MatrixColumn& operator=( const Rcpp::VectorBase& rhs ){ + sugar::check_assign_size(n, rhs.size()) ; + if( ! traits::is_elementwise::value ){ // rhs may read from this column's matrix, so evaluate it first const Vector tmp(rhs) ; @@ -78,6 +80,8 @@ class MatrixColumn : public VectorBase > { } MatrixColumn& operator=( const MatrixColumn& rhs ){ + sugar::check_assign_size(n, rhs.n) ; + iterator rhs_start = rhs.start ; RCPP_LOOP_UNROLL(start,rhs_start) return *this ; diff --git a/inst/include/Rcpp/vector/MatrixRow.h b/inst/include/Rcpp/vector/MatrixRow.h index 6266eef4b..7dc419832 100644 --- a/inst/include/Rcpp/vector/MatrixRow.h +++ b/inst/include/Rcpp/vector/MatrixRow.h @@ -153,6 +153,8 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow > { template MatrixRow& operator=( const Rcpp::VectorBase& rhs ){ + sugar::check_assign_size(size(), rhs.size()) ; + if( ! traits::is_elementwise::value ){ // rhs may read from this row's matrix, so evaluate it first const Vector tmp(rhs) ; @@ -166,6 +168,8 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow > { } MatrixRow& operator=( const MatrixRow& rhs ){ + sugar::check_assign_size(size(), rhs.size()) ; + int n = size() ; RCPP_LOOP_UNROLL_LHSFUN(start,get_parent_index,rhs) return *this ; diff --git a/inst/include/Rcpp/vector/RangeIndexer.h b/inst/include/Rcpp/vector/RangeIndexer.h index 1c4edf629..bcc423d90 100644 --- a/inst/include/Rcpp/vector/RangeIndexer.h +++ b/inst/include/Rcpp/vector/RangeIndexer.h @@ -24,6 +24,7 @@ #define Rcpp__vector__RangeIndexer_h #define UNROLL_LOOP(OP) \ + ::Rcpp::sugar::check_assign_size(size_, x.size()) ; \ if( ! ::Rcpp::traits::is_elementwise::value ){ \ /* x may read from the vector this range */ \ /* indexes, so evaluate it first */ \ diff --git a/inst/tinytest/cpp/sugar_expressions.cpp b/inst/tinytest/cpp/sugar_expressions.cpp index 4b0e3ef75..cc95d0404 100644 --- a/inst/tinytest/cpp/sugar_expressions.cpp +++ b/inst/tinytest/cpp/sugar_expressions.cpp @@ -199,3 +199,51 @@ LogicalVector elementwise_flags(NumericVector x, NumericMatrix m) { _["column"] = column ); } + +// [[Rcpp::export]] +NumericVector length_plus(NumericVector x, NumericVector y) { + return x + y; +} + +// [[Rcpp::export]] +NumericVector length_plus_scalar(NumericVector x) { + return x + 1.0; +} + +// [[Rcpp::export]] +LogicalVector length_compare(NumericVector x, NumericVector y) { + return x < y; +} + +// [[Rcpp::export]] +LogicalVector length_and(LogicalVector x, LogicalVector y) { + return x & y; +} + +// [[Rcpp::export]] +NumericVector length_pmax(NumericVector x, NumericVector y) { + return pmax(x, y); +} + +// [[Rcpp::export]] +NumericVector length_ifelse(LogicalVector cond, NumericVector x, NumericVector y) { + return ifelse(cond, x, y); +} + +// [[Rcpp::export]] +NumericVector length_range(NumericVector x, NumericVector y) { + x[Range(0, 2)] = y; + return x; +} + +// [[Rcpp::export]] +NumericMatrix length_column(NumericMatrix m, NumericVector y) { + m(_, 0) = y; + return m; +} + +// [[Rcpp::export]] +NumericMatrix length_row(NumericMatrix m, NumericVector y) { + m(0, _) = y; + return m; +} diff --git a/inst/tinytest/test_sugar.R b/inst/tinytest/test_sugar.R index 5054d40bf..29fc99c40 100644 --- a/inst/tinytest/test_sugar.R +++ b/inst/tinytest/test_sugar.R @@ -1754,3 +1754,21 @@ expect_equal( rev = FALSE, arith_rev = FALSE, head = FALSE, column = FALSE), info = "traits::is_elementwise" ) + +## sugar doesn't recycle: the vectors combined by an expression, and a vector +## assigned into a range, row or column, must have matching lengths +expect_equal(length_plus(c(1, 2), c(10, 20)), c(11, 22), info = "x + y, same length") +expect_equal(length_plus(numeric(), numeric()), numeric(), info = "x + y, both empty") +expect_equal(length_plus_scalar(c(1, 2)), c(2, 3), info = "x + scalar") +expect_error(length_plus(c(1, 2, 3, 4, 5), c(10, 20)), "different lengths", info = "x + ") +expect_error(length_plus(c(1, 2), c(10, 20, 30, 40)), "different lengths", info = "x + ") +expect_error(length_compare(c(1, 2, 3), c(1, 2)), "different lengths", info = "x < y") +expect_error(length_and(c(TRUE, FALSE), TRUE), "different lengths", info = "x & y") +expect_error(length_pmax(c(1, 2, 3), c(1, 2)), "different lengths", info = "pmax(x, y)") +expect_error(length_ifelse(c(TRUE, FALSE), c(1, 2), c(1, 2, 3)), "different lengths", info = "ifelse(c, x, y)") + +expect_equal(length_range(c(1, 2, 3, 4, 5), c(7, 8, 9)), c(7, 8, 9, 4, 5), info = "x[0:2] = y") +expect_error(length_range(c(1, 2, 3, 4, 5), c(7, 8)), "cannot assign", info = "x[0:2] = ") +expect_error(length_range(c(1, 2, 3, 4, 5), c(6, 7, 8, 9)), "cannot assign", info = "x[0:2] = ") +expect_error(length_column(matrix(1, 3, 2), c(7, 8)), "cannot assign", info = "m(_, 0) = ") +expect_error(length_row(matrix(1, 3, 2), c(7, 8, 9)), "cannot assign", info = "m(0, _) = ") From 617bb03de296c93212d0be09933a312bc35b51ed Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 12:06:49 -0700 Subject: [PATCH 04/11] let rows and columns read matching views in place Evaluating every expression that reads a view into a temporary made updates like `m(_, j) = m(_, j) * 2` several times slower. Whether reading a view in place is safe depends on where the result is written: a column can read other columns of the same matrix (they coincide or are disjoint), a row other rows, and a whole vector any view, but a range can't read another range. Sugar expressions now list their elementwise operands, views declare what kind of view they are, and each write site checks the expression against its own kind of target. Part of #1512. --- inst/include/Rcpp/stats/dpq/dpq.h | 24 ++-- inst/include/Rcpp/sugar/block/SugarBlock_1.h | 2 +- inst/include/Rcpp/sugar/block/SugarBlock_2.h | 6 +- inst/include/Rcpp/sugar/block/SugarBlock_3.h | 2 +- inst/include/Rcpp/sugar/block/SugarMath.h | 6 +- .../Rcpp/sugar/block/Vectorized_Math.h | 6 +- inst/include/Rcpp/sugar/functions/clamp.h | 2 +- inst/include/Rcpp/sugar/functions/complex.h | 2 +- inst/include/Rcpp/sugar/functions/ifelse.h | 16 +-- inst/include/Rcpp/sugar/functions/is_finite.h | 2 +- .../Rcpp/sugar/functions/is_infinite.h | 2 +- inst/include/Rcpp/sugar/functions/is_na.h | 4 +- inst/include/Rcpp/sugar/functions/is_nan.h | 2 +- inst/include/Rcpp/sugar/functions/pmax.h | 4 +- inst/include/Rcpp/sugar/functions/pmin.h | 4 +- inst/include/Rcpp/sugar/functions/pow.h | 6 +- inst/include/Rcpp/sugar/functions/rep.h | 2 +- inst/include/Rcpp/sugar/functions/seq_along.h | 2 +- inst/include/Rcpp/sugar/functions/sign.h | 2 +- inst/include/Rcpp/sugar/logical/and.h | 8 +- inst/include/Rcpp/sugar/logical/or.h | 8 +- inst/include/Rcpp/sugar/nona/nona.h | 4 +- .../include/Rcpp/sugar/operators/Comparator.h | 6 +- .../operators/Comparator_With_One_Value.h | 4 +- inst/include/Rcpp/sugar/operators/divides.h | 32 +++--- inst/include/Rcpp/sugar/operators/minus.h | 32 +++--- inst/include/Rcpp/sugar/operators/not.h | 2 +- inst/include/Rcpp/sugar/operators/plus.h | 32 +++--- inst/include/Rcpp/sugar/operators/times.h | 32 +++--- .../Rcpp/sugar/operators/unary_minus.h | 2 +- inst/include/Rcpp/traits/is_elementwise.h | 106 +++++++++++++----- inst/include/Rcpp/vector/MatrixColumn.h | 4 +- inst/include/Rcpp/vector/MatrixRow.h | 4 +- inst/include/Rcpp/vector/RangeIndexer.h | 3 +- inst/include/Rcpp/vector/Vector.h | 2 +- inst/tinytest/cpp/sugar_expressions.cpp | 73 +++++++++--- inst/tinytest/test_sugar.R | 14 ++- 37 files changed, 287 insertions(+), 177 deletions(-) diff --git a/inst/include/Rcpp/stats/dpq/dpq.h b/inst/include/Rcpp/stats/dpq/dpq.h index 4e084b4a7..c68ab8029 100644 --- a/inst/include/Rcpp/stats/dpq/dpq.h +++ b/inst/include/Rcpp/stats/dpq/dpq.h @@ -35,7 +35,7 @@ class D0 : public Rcpp::VectorBase< REALSXP, NA, D0 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; D0( FunPtr ptr_, const VEC_TYPE& vec_, bool log_ ) : ptr(ptr_), vec(vec_.get_ref()), log(log_) {} @@ -57,7 +57,7 @@ class D1 : public Rcpp::VectorBase< REALSXP, NA, D1 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; D1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_ , bool log_) : ptr(ptr_), vec(vec_.get_ref()), p0(p0_), log(log_) {} @@ -80,7 +80,7 @@ class D2 : public Rcpp::VectorBase< REALSXP, NA, D2 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; D2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_ , bool log_) : ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), log(log_) {} @@ -103,7 +103,7 @@ class D3 : public Rcpp::VectorBase< REALSXP, NA, D3 > { public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,double,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; D3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_ , bool log_ ) : ptr(ptr_), vec(vec_.get_ref()), p0(p0_), p1(p1_), p2(p2_), log(log_) {} @@ -129,7 +129,7 @@ class P0 : public Rcpp::VectorBase< REALSXP, NA, P0 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; P0( FunPtr ptr_, const VEC_TYPE& vec_, bool lower_tail = true, bool log_ = false ) : @@ -154,7 +154,7 @@ class P1 : public Rcpp::VectorBase< REALSXP, NA, P1 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; P1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, bool lower_tail = true, bool log_ = false ) : @@ -180,7 +180,7 @@ class P2 : public Rcpp::VectorBase< REALSXP, NA, P2 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; P2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, bool lower_tail = true, bool log_ = false ) : @@ -204,7 +204,7 @@ class P3 : public Rcpp::VectorBase< REALSXP, NA, P3 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; P3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_, bool lower_tail = true, bool log_ = false ) : @@ -231,7 +231,7 @@ class Q0 : public Rcpp::VectorBase< REALSXP, NA, Q0 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Q0( FunPtr ptr_, const VEC_TYPE& vec_, bool lower_tail = true, bool log_ = false ) : @@ -255,7 +255,7 @@ class Q1 : public Rcpp::VectorBase< REALSXP, NA, Q1 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Q1( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, bool lower_tail = true, bool log_ = false ) : @@ -280,7 +280,7 @@ class Q2 : public Rcpp::VectorBase< REALSXP, NA, Q2 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Q2( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, bool lower_tail = true, bool log_ = false ) : @@ -305,7 +305,7 @@ class Q3 : public Rcpp::VectorBase< REALSXP, NA, Q3 >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef double (*FunPtr)(double,double,double,double,int,int) ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Q3( FunPtr ptr_, const VEC_TYPE& vec_, double p0_, double p1_, double p2_, bool lower_tail = true, bool log_ = false ) : diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_1.h b/inst/include/Rcpp/sugar/block/SugarBlock_1.h index abe81d791..fff2fc6a2 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_1.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_1.h @@ -29,7 +29,7 @@ template class SugarBlock_1 : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype , NA, SugarBlock_1 > { public: typedef RESULT_TYPE (*FunPtr)(U1) ; - typedef Rcpp::traits::is_elementwise< T1 > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T1 > rcpp_elementwise ; SugarBlock_1( FunPtr ptr_, const T1 & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_2.h b/inst/include/Rcpp/sugar/block/SugarBlock_2.h index 88aa65475..14ecd242f 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_2.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_2.h @@ -29,7 +29,7 @@ template ::rtype , NA, SugarBlock_2 > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; - typedef Rcpp::traits::are_elementwise< T1, T2 > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T1, T2 > rcpp_elementwise ; SugarBlock_2( FunPtr ptr_, const T1 & x_, const T2& y_ ) : ptr(ptr_), x(x_.get_ref()), y(y_.get_ref()){ check_sizes(x.size(), y.size()) ; @@ -51,7 +51,7 @@ template class SugarBlock_2__VP : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype , NA, SugarBlock_2__VP > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; - typedef Rcpp::traits::is_elementwise< T1 > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T1 > rcpp_elementwise ; SugarBlock_2__VP( FunPtr ptr_, const T1 & x_, U2 u2 ) : ptr(ptr_), x(x_.get_ref()), y(u2){} @@ -70,7 +70,7 @@ template class SugarBlock_2__PV : public Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype , NA, SugarBlock_2__PV > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2) ; - typedef Rcpp::traits::is_elementwise< T2 > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T2 > rcpp_elementwise ; SugarBlock_2__PV( FunPtr ptr_, U1 u1, const T2& y_ ) : ptr(ptr_), x(u1), y(y_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/block/SugarBlock_3.h b/inst/include/Rcpp/sugar/block/SugarBlock_3.h index 2f41a0fa6..4e90a454d 100644 --- a/inst/include/Rcpp/sugar/block/SugarBlock_3.h +++ b/inst/include/Rcpp/sugar/block/SugarBlock_3.h @@ -37,7 +37,7 @@ class SugarBlock_3_VVV : public Rcpp::VectorBase< SugarBlock_3_VVV > { public: typedef RESULT_TYPE (*FunPtr)(U1,U2,U3) ; - typedef Rcpp::traits::are_elementwise< T1, T2, T3 > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T1, T2, T3 > rcpp_elementwise ; SugarBlock_3_VVV( FunPtr ptr_, const T1 & x_, const T2& y_, const T3& z_ ) : ptr(ptr_), x(x_.get_ref()), y(y_.get_ref()), z(z_.get_ref()) { check_sizes(x.size(), y.size(), z.size()) ; diff --git a/inst/include/Rcpp/sugar/block/SugarMath.h b/inst/include/Rcpp/sugar/block/SugarMath.h index c32507777..f38208cfd 100644 --- a/inst/include/Rcpp/sugar/block/SugarMath.h +++ b/inst/include/Rcpp/sugar/block/SugarMath.h @@ -34,7 +34,7 @@ class SugarMath_1 : public Rcpp::VectorBase< public: typedef Rcpp::VectorBase< Rcpp::traits::r_sexptype_traits::rtype ,NA,T1> VEC_TYPE ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} @@ -58,7 +58,7 @@ class SugarMath_1 : public Rcpp::VectorBase< > { public: typedef Rcpp::VectorBase< INTSXP ,NA,T1> VEC_TYPE ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} @@ -83,7 +83,7 @@ Rcpp::VectorBase< > { public: typedef Rcpp::VectorBase< INTSXP ,false,T1> VEC_TYPE ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; SugarMath_1( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} inline RESULT_TYPE operator[]( R_xlen_t i) const { diff --git a/inst/include/Rcpp/sugar/block/Vectorized_Math.h b/inst/include/Rcpp/sugar/block/Vectorized_Math.h index 1b4a0819f..314aa08c4 100644 --- a/inst/include/Rcpp/sugar/block/Vectorized_Math.h +++ b/inst/include/Rcpp/sugar/block/Vectorized_Math.h @@ -32,7 +32,7 @@ class Vectorized : public VectorBase >{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Vectorized( const VEC_TYPE& object_) : object( object_.get_ref() ){} inline double operator[]( R_xlen_t i) const { @@ -49,7 +49,7 @@ class Vectorized_INTSXP : public VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Vectorized_INTSXP( const VEC_TYPE& object_) : object( object_.get_ref() ){} inline double operator[]( R_xlen_t i) const { @@ -68,7 +68,7 @@ class Vectorized_INTSXP : public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Vectorized_INTSXP( const VEC_TYPE& object_) : object( object_.get_ref() ){} inline double operator[]( R_xlen_t i) const { diff --git a/inst/include/Rcpp/sugar/functions/clamp.h b/inst/include/Rcpp/sugar/functions/clamp.h index 70d5689da..2950b6235 100644 --- a/inst/include/Rcpp/sugar/functions/clamp.h +++ b/inst/include/Rcpp/sugar/functions/clamp.h @@ -62,7 +62,7 @@ class Clamp_Primitive_Vector_Primitive : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef clamp_operator OPERATOR ; - typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T > rcpp_elementwise ; Clamp_Primitive_Vector_Primitive( STORAGE lhs_, const T& vec_, STORAGE rhs_) : vec(vec_), op(lhs_,rhs_) {} diff --git a/inst/include/Rcpp/sugar/functions/complex.h b/inst/include/Rcpp/sugar/functions/complex.h index 76d99d6e8..6ad60ca2e 100644 --- a/inst/include/Rcpp/sugar/functions/complex.h +++ b/inst/include/Rcpp/sugar/functions/complex.h @@ -35,7 +35,7 @@ class SugarComplex : public Rcpp::VectorBase< public: typedef Rcpp::VectorBase VEC_TYPE ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; SugarComplex( FunPtr ptr_, const VEC_TYPE & vec_) : ptr(ptr_), vec(vec_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/functions/ifelse.h b/inst/include/Rcpp/sugar/functions/ifelse.h index 22f8090d7..0b2de8f2b 100644 --- a/inst/include/Rcpp/sugar/functions/ifelse.h +++ b/inst/include/Rcpp/sugar/functions/ifelse.h @@ -41,7 +41,7 @@ class IfElse : public VectorBase< typedef Rcpp::VectorBase LHS_TYPE ; typedef Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; - typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_T, RHS_T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE, LHS_T, RHS_T > rcpp_elementwise ; // typedef typename Rcpp::traits::Extractor::type LHS_EXT ; // typedef typename Rcpp::traits::Extractor::type RHS_EXT ; @@ -88,7 +88,7 @@ class IfElse : public VectorBase< typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE, LHS_EXT, RHS_EXT > rcpp_elementwise ; IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -129,7 +129,7 @@ class IfElse_Primitive_Vector : public VectorBase< typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< COND_TYPE, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE, RHS_EXT > rcpp_elementwise ; IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { @@ -167,7 +167,7 @@ class IfElse_Primitive_Vector : public VectorBa typedef Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< COND_TYPE, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE, RHS_EXT > rcpp_elementwise ; IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_.get_ref()) { @@ -207,7 +207,7 @@ class IfElse_Vector_Primitive : public VectorBase< typedef Rcpp::VectorBase LHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; - typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE, LHS_EXT > rcpp_elementwise ; IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { @@ -245,7 +245,7 @@ class IfElse_Vector_Primitive : public VectorBa typedef Rcpp::VectorBase LHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; - typedef Rcpp::traits::are_elementwise< COND_TYPE, LHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE, LHS_EXT > rcpp_elementwise ; IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_.get_ref()), rhs(rhs_) { @@ -284,7 +284,7 @@ class IfElse_Primitive_Primitive : public VectorBase< public: typedef Rcpp::VectorBase COND_TYPE ; typedef typename traits::storage_type::type STORAGE ; - typedef Rcpp::traits::is_elementwise< COND_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE > rcpp_elementwise ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { @@ -318,7 +318,7 @@ class IfElse_Primitive_Primitive : public VectorBase< public: typedef Rcpp::VectorBase COND_TYPE ; typedef typename traits::storage_type::type STORAGE ; - typedef Rcpp::traits::is_elementwise< COND_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< COND_TYPE > rcpp_elementwise ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { diff --git a/inst/include/Rcpp/sugar/functions/is_finite.h b/inst/include/Rcpp/sugar/functions/is_finite.h index 059478132..589ff629c 100644 --- a/inst/include/Rcpp/sugar/functions/is_finite.h +++ b/inst/include/Rcpp/sugar/functions/is_finite.h @@ -29,7 +29,7 @@ template class IsFinite : public ::Rcpp::VectorBase< LGLSXP, false, IsFinite > { public: - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; IsFinite( const VEC_TYPE& obj_) : obj(obj_){} diff --git a/inst/include/Rcpp/sugar/functions/is_infinite.h b/inst/include/Rcpp/sugar/functions/is_infinite.h index c1703ef67..846645b34 100644 --- a/inst/include/Rcpp/sugar/functions/is_infinite.h +++ b/inst/include/Rcpp/sugar/functions/is_infinite.h @@ -29,7 +29,7 @@ template class IsInfinite : public ::Rcpp::VectorBase< LGLSXP, false, IsInfinite > { public: - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; IsInfinite( const VEC_TYPE& obj_) : obj(obj_){} diff --git a/inst/include/Rcpp/sugar/functions/is_na.h b/inst/include/Rcpp/sugar/functions/is_na.h index 41b200b3a..ecbfb6fc9 100644 --- a/inst/include/Rcpp/sugar/functions/is_na.h +++ b/inst/include/Rcpp/sugar/functions/is_na.h @@ -31,7 +31,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsNa > public: typedef typename traits::storage_type::type STORAGE ; typedef Rcpp::VectorBase BASE ; - typedef Rcpp::traits::is_elementwise< BASE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< BASE > rcpp_elementwise ; IsNa( const BASE& obj_) : obj(obj_.get_ref()){} @@ -54,7 +54,7 @@ class IsNa : public ::Rcpp::VectorBase< LGLSXP, false, IsN public: typedef typename traits::storage_type::type STORAGE ; typedef Rcpp::VectorBase BASE ; - typedef Rcpp::traits::is_elementwise< BASE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< BASE > rcpp_elementwise ; IsNa( const BASE& obj_) : obj(obj_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/functions/is_nan.h b/inst/include/Rcpp/sugar/functions/is_nan.h index 82f60320b..492970797 100644 --- a/inst/include/Rcpp/sugar/functions/is_nan.h +++ b/inst/include/Rcpp/sugar/functions/is_nan.h @@ -29,7 +29,7 @@ template class IsNaN : public ::Rcpp::VectorBase< LGLSXP, false, IsNaN > { public: - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; IsNaN( const VEC_TYPE& obj_) : obj(obj_){} diff --git a/inst/include/Rcpp/sugar/functions/pmax.h b/inst/include/Rcpp/sugar/functions/pmax.h index aeb00eea9..9c497f4c4 100644 --- a/inst/include/Rcpp/sugar/functions/pmax.h +++ b/inst/include/Rcpp/sugar/functions/pmax.h @@ -104,7 +104,7 @@ class Pmax_Vector_Vector : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmax_op OPERATOR ; - typedef Rcpp::traits::are_elementwise< LHS_T, RHS_T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_T, RHS_T > rcpp_elementwise ; Pmax_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() { check_sizes(lhs.size(), rhs.size()) ; @@ -135,7 +135,7 @@ class Pmax_Vector_Primitive : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmax_op_Vector_Primitive OPERATOR ; - typedef Rcpp::traits::is_elementwise< LHS_T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_T > rcpp_elementwise ; Pmax_Vector_Primitive( const LHS_T& lhs_, STORAGE rhs_ ) : lhs(lhs_), op(rhs_) {} diff --git a/inst/include/Rcpp/sugar/functions/pmin.h b/inst/include/Rcpp/sugar/functions/pmin.h index 696b6594d..b81d64f15 100644 --- a/inst/include/Rcpp/sugar/functions/pmin.h +++ b/inst/include/Rcpp/sugar/functions/pmin.h @@ -104,7 +104,7 @@ class Pmin_Vector_Vector : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmin_op OPERATOR ; - typedef Rcpp::traits::are_elementwise< LHS_T, RHS_T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_T, RHS_T > rcpp_elementwise ; Pmin_Vector_Vector( const LHS_T& lhs_, const RHS_T& rhs_ ) : lhs(lhs_), rhs(rhs_), op() { check_sizes(lhs.size(), rhs.size()) ; @@ -135,7 +135,7 @@ class Pmin_Vector_Primitive : public VectorBase< public: typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef pmin_op_Vector_Primitive OPERATOR ; - typedef Rcpp::traits::is_elementwise< LHS_T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_T > rcpp_elementwise ; Pmin_Vector_Primitive( const LHS_T& lhs_, STORAGE rhs_ ) : lhs(lhs_), op(rhs_) {} diff --git a/inst/include/Rcpp/sugar/functions/pow.h b/inst/include/Rcpp/sugar/functions/pow.h index ed4ca438a..ad0a573ca 100644 --- a/inst/include/Rcpp/sugar/functions/pow.h +++ b/inst/include/Rcpp/sugar/functions/pow.h @@ -29,7 +29,7 @@ template class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow > { public: typedef typename Rcpp::traits::storage_type::type STORAGE ; - typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T > rcpp_elementwise ; Pow( const T& object_, EXPONENT_TYPE exponent ) : object(object_), op(exponent) {} @@ -46,7 +46,7 @@ class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow template class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow > { public: - typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T > rcpp_elementwise ; Pow( const T& object_, EXPONENT_TYPE exponent ) : object(object_), op(exponent) {} @@ -63,7 +63,7 @@ class Pow : public Rcpp::VectorBase< REALSXP ,NA, Pow template class Pow : public Rcpp::VectorBase< REALSXP ,false, Pow > { public: - typedef Rcpp::traits::is_elementwise< T > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< T > rcpp_elementwise ; Pow( const T& object_, EXPONENT_TYPE exponent ) : object(object_), op(exponent) {} diff --git a/inst/include/Rcpp/sugar/functions/rep.h b/inst/include/Rcpp/sugar/functions/rep.h index adc389020..011fec553 100644 --- a/inst/include/Rcpp/sugar/functions/rep.h +++ b/inst/include/Rcpp/sugar/functions/rep.h @@ -51,7 +51,7 @@ class Rep_Single : public Rcpp::VectorBase< Rep_Single > { public: - typedef Rcpp::traits::true_type rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands<> rcpp_elementwise ; Rep_Single( const T& x_, R_xlen_t n_) : x(x_), n(n_){} diff --git a/inst/include/Rcpp/sugar/functions/seq_along.h b/inst/include/Rcpp/sugar/functions/seq_along.h index 88e09cfd3..11cd319c4 100644 --- a/inst/include/Rcpp/sugar/functions/seq_along.h +++ b/inst/include/Rcpp/sugar/functions/seq_along.h @@ -28,7 +28,7 @@ namespace sugar{ class SeqLen : public VectorBase< INTSXP,false,SeqLen > { public: - typedef Rcpp::traits::true_type rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands<> rcpp_elementwise ; SeqLen( R_xlen_t len_ ) : len(len_){} diff --git a/inst/include/Rcpp/sugar/functions/sign.h b/inst/include/Rcpp/sugar/functions/sign.h index 4f0cc41ff..9ecc0490b 100644 --- a/inst/include/Rcpp/sugar/functions/sign.h +++ b/inst/include/Rcpp/sugar/functions/sign.h @@ -50,7 +50,7 @@ class Sign : public Rcpp::VectorBase< INTSXP,NA, Sign > { typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef int r_import_type ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Sign( const VEC_TYPE& object_ ) : object(object_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/logical/and.h b/inst/include/Rcpp/sugar/logical/and.h index e3ddb5cbf..dcb4bd1b8 100644 --- a/inst/include/Rcpp/sugar/logical/and.h +++ b/inst/include/Rcpp/sugar/logical/and.h @@ -206,7 +206,7 @@ class And_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; @@ -229,7 +229,7 @@ class And_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; @@ -252,7 +252,7 @@ class And_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; @@ -275,7 +275,7 @@ class And_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; And_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; diff --git a/inst/include/Rcpp/sugar/logical/or.h b/inst/include/Rcpp/sugar/logical/or.h index 1a2dd5823..c85d3b390 100644 --- a/inst/include/Rcpp/sugar/logical/or.h +++ b/inst/include/Rcpp/sugar/logical/or.h @@ -203,7 +203,7 @@ class Or_LogicalExpression_LogicalExpression : public Rcpp::VectorBase< LGLSXP, public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; @@ -226,7 +226,7 @@ class Or_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; @@ -249,7 +249,7 @@ class Or_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; @@ -272,7 +272,7 @@ class Or_LogicalExpression_LogicalExpression public: typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Or_LogicalExpression_LogicalExpression( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ check_sizes(lhs.size(), rhs.size()) ; diff --git a/inst/include/Rcpp/sugar/nona/nona.h b/inst/include/Rcpp/sugar/nona/nona.h index 3764bdd3a..fecd32ef7 100644 --- a/inst/include/Rcpp/sugar/nona/nona.h +++ b/inst/include/Rcpp/sugar/nona/nona.h @@ -30,7 +30,7 @@ namespace sugar { public: typedef typename Rcpp::VectorBase SUGAR_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; - typedef Rcpp::traits::is_elementwise< VECTOR > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VECTOR > rcpp_elementwise ; Nona( const SUGAR_TYPE& expr) : data(expr.get_ref()){} @@ -48,7 +48,7 @@ namespace sugar { typedef typename Rcpp::VectorBase > SUGAR_TYPE ; typedef typename Rcpp::traits::storage_type::type STORAGE ; typedef typename Rcpp::Vector::const_iterator iterator ; - typedef Rcpp::traits::true_type rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands<> rcpp_elementwise ; Nona( const SUGAR_TYPE& expr) : data(expr.get_ref().begin()), n(expr.size()){} diff --git a/inst/include/Rcpp/sugar/operators/Comparator.h b/inst/include/Rcpp/sugar/operators/Comparator.h index 4832dbb9f..61121c06c 100644 --- a/inst/include/Rcpp/sugar/operators/Comparator.h +++ b/inst/include/Rcpp/sugar/operators/Comparator.h @@ -33,7 +33,7 @@ class Comparator : typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() { @@ -67,7 +67,7 @@ class Comparator : typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() { @@ -98,7 +98,7 @@ class Comparator : typedef typename Rcpp::VectorBase LHS_TYPE ; typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename traits::storage_type::type STORAGE ; - typedef Rcpp::traits::are_elementwise< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_TYPE, RHS_TYPE > rcpp_elementwise ; Comparator( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()), op() { diff --git a/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h b/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h index 4c8a7c525..243a45ce2 100644 --- a/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h +++ b/inst/include/Rcpp/sugar/operators/Comparator_With_One_Value.h @@ -32,7 +32,7 @@ class Comparator_With_One_Value : public ::Rcpp::VectorBase< LGLSXP, true, Compa typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef int (Comparator_With_One_Value::*METHOD)(R_xlen_t) const ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Comparator_With_One_Value( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), m(), op() { @@ -72,7 +72,7 @@ class Comparator_With_One_Value : typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef int (Comparator_With_One_Value::*METHOD)(R_xlen_t) const ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Comparator_With_One_Value( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), m(), op() { diff --git a/inst/include/Rcpp/sugar/operators/divides.h b/inst/include/Rcpp/sugar/operators/divides.h index b2ab1f42b..3ca732231 100644 --- a/inst/include/Rcpp/sugar/operators/divides.h +++ b/inst/include/Rcpp/sugar/operators/divides.h @@ -33,7 +33,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -62,7 +62,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -89,7 +89,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -117,7 +117,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -145,7 +145,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -172,7 +172,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -199,7 +199,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -225,7 +225,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Divides_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -253,7 +253,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) { @@ -279,7 +279,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) { @@ -305,7 +305,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -329,7 +329,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_){} @@ -353,7 +353,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; typedef typename traits::storage_type::type STORAGE ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -376,7 +376,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()) {} @@ -399,7 +399,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -422,7 +422,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Divides_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()) {} diff --git a/inst/include/Rcpp/sugar/operators/minus.h b/inst/include/Rcpp/sugar/operators/minus.h index 68c7e3ace..b5fd4cad9 100644 --- a/inst/include/Rcpp/sugar/operators/minus.h +++ b/inst/include/Rcpp/sugar/operators/minus.h @@ -35,7 +35,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -64,7 +64,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -91,7 +91,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -119,7 +119,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -146,7 +146,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -174,7 +174,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -202,7 +202,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -227,7 +227,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase RHS_TYPE ; typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Minus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -256,7 +256,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -280,7 +280,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_){} @@ -304,7 +304,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -328,7 +328,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_){} @@ -356,7 +356,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -378,7 +378,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()){} @@ -402,7 +402,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( STORAGE lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()), lhs_na( Rcpp::traits::is_na(lhs_) ) {} @@ -426,7 +426,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type VEC_EXT ; - typedef Rcpp::traits::is_elementwise< VEC_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_EXT > rcpp_elementwise ; Minus_Primitive_Vector( double lhs_, const VEC_TYPE& rhs_ ) : lhs(lhs_), rhs(rhs_.get_ref()){} diff --git a/inst/include/Rcpp/sugar/operators/not.h b/inst/include/Rcpp/sugar/operators/not.h index e8989d731..d584cbd1b 100644 --- a/inst/include/Rcpp/sugar/operators/not.h +++ b/inst/include/Rcpp/sugar/operators/not.h @@ -78,7 +78,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef not_ OPERATOR ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; Not_Vector( const VEC_TYPE& lhs_ ) : lhs(lhs_.get_ref()), op() {} diff --git a/inst/include/Rcpp/sugar/operators/plus.h b/inst/include/Rcpp/sugar/operators/plus.h index b25817695..683239070 100644 --- a/inst/include/Rcpp/sugar/operators/plus.h +++ b/inst/include/Rcpp/sugar/operators/plus.h @@ -35,7 +35,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -68,7 +68,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -99,7 +99,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -128,7 +128,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -158,7 +158,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -187,7 +187,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -218,7 +218,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -245,7 +245,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -276,7 +276,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) @@ -303,7 +303,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor< REALSXP, NA, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -329,7 +329,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -353,7 +353,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor< REALSXP, false, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -381,7 +381,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -405,7 +405,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -432,7 +432,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -455,7 +455,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor< REALSXP, false, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} diff --git a/inst/include/Rcpp/sugar/operators/times.h b/inst/include/Rcpp/sugar/operators/times.h index f59752d69..8ce3e1e33 100644 --- a/inst/include/Rcpp/sugar/operators/times.h +++ b/inst/include/Rcpp/sugar/operators/times.h @@ -35,7 +35,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -65,7 +65,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) { @@ -94,7 +94,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -123,7 +123,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -152,7 +152,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -181,7 +181,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -209,7 +209,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -236,7 +236,7 @@ namespace sugar{ typedef typename Rcpp::traits::Extractor::type LHS_EXT ; typedef typename Rcpp::traits::Extractor::type RHS_EXT ; - typedef Rcpp::traits::are_elementwise< LHS_EXT, RHS_EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< LHS_EXT, RHS_EXT > rcpp_elementwise ; Times_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){ @@ -262,7 +262,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) @@ -288,7 +288,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -313,7 +313,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na(rhs_) ) {} @@ -337,7 +337,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -365,7 +365,7 @@ namespace sugar{ typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -390,7 +390,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) @@ -415,7 +415,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} @@ -437,7 +437,7 @@ namespace sugar{ public: typedef typename Rcpp::VectorBase VEC_TYPE ; typedef typename Rcpp::traits::Extractor::type EXT ; - typedef Rcpp::traits::is_elementwise< EXT > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< EXT > rcpp_elementwise ; Times_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : lhs(lhs_.get_ref()), rhs(rhs_) {} diff --git a/inst/include/Rcpp/sugar/operators/unary_minus.h b/inst/include/Rcpp/sugar/operators/unary_minus.h index 911d3cd9d..ee298e64e 100644 --- a/inst/include/Rcpp/sugar/operators/unary_minus.h +++ b/inst/include/Rcpp/sugar/operators/unary_minus.h @@ -90,7 +90,7 @@ namespace sugar{ typedef typename traits::storage_type::type STORAGE ; typedef typename unary_minus_result_type::type RESULT ; typedef unary_minus OPERATOR ; - typedef Rcpp::traits::is_elementwise< VEC_TYPE > rcpp_elementwise ; + typedef Rcpp::traits::elementwise_operands< VEC_TYPE > rcpp_elementwise ; UnaryMinus_Vector( const VEC_TYPE& lhs_ ) : lhs(lhs_.get_ref()), op() {} diff --git a/inst/include/Rcpp/traits/is_elementwise.h b/inst/include/Rcpp/traits/is_elementwise.h index 9ddcfa95b..701a69a58 100644 --- a/inst/include/Rcpp/traits/is_elementwise.h +++ b/inst/include/Rcpp/traits/is_elementwise.h @@ -1,7 +1,7 @@ // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- // // is_elementwise.h: Rcpp R/C++ interface class library -- whether a sugar -// expression can be written into one of its own operands in place +// expression can be written in place into storage it may read from // // Copyright (C) 2026 Kevin Ushey // @@ -26,6 +26,41 @@ namespace Rcpp{ namespace traits{ + // Sugar expressions declare `typedef elementwise_operands<...> + // rcpp_elementwise` when their element i depends only on element i of + // those operands, all of which have the expression's length. + template + struct elementwise_operands {} ; + + // Views declare `typedef ... rcpp_view` with the kind of view they are. + struct range_view {} ; + struct column_view {} ; + struct row_view {} ; + + // Where an expression is being written, and so which views it may read + // while it is written in place. Reading a view of the target's own + // storage is harmless if the view always covers either exactly the + // target's positions or none of them: + // + // - a whole vector: given matching lengths, any view of its storage + // covers all of it; + // - a matrix column (row): any other column (row) of the same matrix is + // either the same one or disjoint from it; + // - a range: another range of the same vector may overlap it at an + // offset, so no views are allowed. + struct vector_target { + template struct reads : true_type {} ; + } ; + struct column_target { + template struct reads : same_type {} ; + } ; + struct row_target { + template struct reads : same_type {} ; + } ; + struct range_target { + template struct reads : false_type {} ; + } ; + template class _has_elementwise_marker_helper : __sfinae_types { template static __one __test(typename U::rcpp_elementwise*); @@ -34,38 +69,57 @@ namespace traits{ static const bool value = sizeof(__test(0)) == 1; }; - // An expression is elementwise when its element i depends only on - // element i of the vectors it reads, all of which have the expression's - // length. Writing such an expression into one of those vectors (or a - // view of one) in place is safe; anything else has to be evaluated into - // a temporary first. - // - // Vectors and matrices are elementwise; sugar expressions opt in with a - // nested `rcpp_elementwise` type (usually defined in terms of their - // operands), and are assumed not to be elementwise otherwise. + template + class _has_view_tag_helper : __sfinae_types { + template static __one __test(typename U::rcpp_view*); + template static __two __test(...); + public: + static const bool value = sizeof(__test(0)) == 1; + }; + + template + struct _operands_are_elementwise : false_type {} ; + + // Whether an expression can be written in place into TARGET even if it + // reads from TARGET's storage, i.e. whether it is elementwise. Vectors + // and matrices are; views are if TARGET allows them; sugar expressions + // are if they declare elementwise operands that are. Anything else is + // assumed not to be, and has to be evaluated before it is written. template < typename T, + typename TARGET, bool = _has_storage_policy_helper::value, - bool = _has_elementwise_marker_helper::value + bool = _has_elementwise_marker_helper::value, + bool = _has_view_tag_helper::value > struct is_elementwise : false_type {} ; - template - struct is_elementwise : true_type {} ; + template + struct is_elementwise : true_type {} ; - template - struct is_elementwise : - integral_constant {} ; - - template - struct is_elementwise< VectorBase, false, false > : is_elementwise {} ; - - template - struct are_elementwise : integral_constant::value && - is_elementwise::value && - is_elementwise::value - > {} ; + template + struct is_elementwise : + _operands_are_elementwise {} ; + + template + struct is_elementwise : + TARGET::template reads {} ; + + // unused operand slots + template + struct is_elementwise : true_type {} ; + + template + struct is_elementwise< VectorBase, TARGET, false, false, false > : + is_elementwise {} ; + + template + struct _operands_are_elementwise< elementwise_operands, TARGET > : + integral_constant::value && + is_elementwise::value && + is_elementwise::value + > {} ; } // traits } // Rcpp diff --git a/inst/include/Rcpp/vector/MatrixColumn.h b/inst/include/Rcpp/vector/MatrixColumn.h index 9d997198e..c453228c8 100644 --- a/inst/include/Rcpp/vector/MatrixColumn.h +++ b/inst/include/Rcpp/vector/MatrixColumn.h @@ -28,6 +28,7 @@ namespace Rcpp{ template class MatrixColumn : public VectorBase > { public: + typedef traits::column_view rcpp_view ; typedef Matrix MATRIX ; typedef typename MATRIX::Proxy Proxy ; typedef typename MATRIX::const_Proxy const_Proxy ; @@ -68,7 +69,7 @@ class MatrixColumn : public VectorBase > { MatrixColumn& operator=( const Rcpp::VectorBase& rhs ){ sugar::check_assign_size(n, rhs.size()) ; - if( ! traits::is_elementwise::value ){ + if( ! traits::is_elementwise::value ){ // rhs may read from this column's matrix, so evaluate it first const Vector tmp(rhs) ; return operator=( tmp ) ; @@ -133,6 +134,7 @@ class MatrixColumn : public VectorBase > { template class ConstMatrixColumn : public VectorBase > { public: + typedef traits::column_view rcpp_view ; typedef Matrix MATRIX ; typedef typename MATRIX::const_Proxy const_Proxy ; typedef typename MATRIX::value_type value_type ; diff --git a/inst/include/Rcpp/vector/MatrixRow.h b/inst/include/Rcpp/vector/MatrixRow.h index 7dc419832..9394254b6 100644 --- a/inst/include/Rcpp/vector/MatrixRow.h +++ b/inst/include/Rcpp/vector/MatrixRow.h @@ -28,6 +28,7 @@ namespace Rcpp{ template class MatrixRow : public VectorBase< RTYPE, true, MatrixRow > { public: + typedef traits::row_view rcpp_view ; typedef Matrix MATRIX ; typedef typename MATRIX::Proxy Proxy ; typedef typename MATRIX::Proxy reference ; @@ -155,7 +156,7 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow > { MatrixRow& operator=( const Rcpp::VectorBase& rhs ){ sugar::check_assign_size(size(), rhs.size()) ; - if( ! traits::is_elementwise::value ){ + if( ! traits::is_elementwise::value ){ // rhs may read from this row's matrix, so evaluate it first const Vector tmp(rhs) ; return operator=( tmp ) ; @@ -226,6 +227,7 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow > { template class ConstMatrixRow : public VectorBase< RTYPE, true, ConstMatrixRow > { public: + typedef traits::row_view rcpp_view ; typedef Matrix MATRIX ; typedef typename MATRIX::const_Proxy const_reference ; typedef typename MATRIX::value_type value_type ; diff --git a/inst/include/Rcpp/vector/RangeIndexer.h b/inst/include/Rcpp/vector/RangeIndexer.h index bcc423d90..4a8e57e74 100644 --- a/inst/include/Rcpp/vector/RangeIndexer.h +++ b/inst/include/Rcpp/vector/RangeIndexer.h @@ -25,7 +25,7 @@ #define UNROLL_LOOP(OP) \ ::Rcpp::sugar::check_assign_size(size_, x.size()) ; \ - if( ! ::Rcpp::traits::is_elementwise::value ){ \ + if( ! ::Rcpp::traits::is_elementwise::value ){ \ /* x may read from the vector this range */ \ /* indexes, so evaluate it first */ \ const Vector tmp(x) ; \ @@ -60,6 +60,7 @@ namespace internal{ template class RangeIndexer : public VectorBase > { public: + typedef traits::range_view rcpp_view ; typedef typename VECTOR::Proxy Proxy ; typedef typename VECTOR::iterator iterator ; diff --git a/inst/include/Rcpp/vector/Vector.h b/inst/include/Rcpp/vector/Vector.h index 751cf4d82..d8f6ed4e8 100644 --- a/inst/include/Rcpp/vector/Vector.h +++ b/inst/include/Rcpp/vector/Vector.h @@ -1054,7 +1054,7 @@ class Vector : // write into the existing storage; an expression that isn't // elementwise may read from this vector (e.g. `x = rev(x)`), so // evaluate it first - if( traits::is_elementwise::value ){ + if( traits::is_elementwise::value ){ import_expression(x, n ) ; } else { const Vector< T::r_type::value > tmp(x) ; diff --git a/inst/tinytest/cpp/sugar_expressions.cpp b/inst/tinytest/cpp/sugar_expressions.cpp index cc95d0404..028e4fd71 100644 --- a/inst/tinytest/cpp/sugar_expressions.cpp +++ b/inst/tinytest/cpp/sugar_expressions.cpp @@ -175,28 +175,69 @@ NumericMatrix alias_row_rev(NumericMatrix m) { return m; } +// [[Rcpp::export]] +NumericMatrix alias_column_scale(NumericMatrix m) { + for (int j = 0; j < m.ncol(); j++) + m(_, j) = m(_, j) * 2.0; + return m; +} + +// [[Rcpp::export]] +NumericMatrix alias_row_scale(NumericMatrix m) { + for (int i = 0; i < m.nrow(); i++) + m(i, _) = m(i, _) * 2.0; + return m; +} + +// [[Rcpp::export]] +NumericMatrix alias_row_from_column(NumericMatrix m) { + m(2, _) = m(_, 0) * 1.0; + return m; +} + +// [[Rcpp::export]] +NumericMatrix alias_column_from_row(NumericMatrix m) { + m(_, 2) = m(0, _) * 1.0; + return m; +} + +typedef traits::vector_target VT; +typedef traits::column_target CT; +typedef traits::row_target RT; +typedef traits::range_target GT; + // [[Rcpp::export]] LogicalVector elementwise_flags(NumericVector x, NumericMatrix m) { // copy into locals, since binding the static `value` members by // reference would require them to have definitions - bool vector = traits::is_elementwise::value; - bool arith = traits::is_elementwise::value; - bool math = traits::is_elementwise::value; - bool if_else = traits::is_elementwise 0.0, x, -x))>::value; - bool reversed = traits::is_elementwise::value; - bool arith_rev = traits::is_elementwise::value; - bool first = traits::is_elementwise::value; - bool column = traits::is_elementwise::value; + bool vector = traits::is_elementwise::value; + bool arith = traits::is_elementwise::value; + bool math = traits::is_elementwise::value; + bool if_else = traits::is_elementwise 0.0, x, -x)), GT>::value; + bool reversed = traits::is_elementwise::value; + bool arith_rev = traits::is_elementwise::value; + bool first = traits::is_elementwise::value; + bool column_vector = traits::is_elementwise::value; + bool column_column = traits::is_elementwise::value; + bool column_row = traits::is_elementwise::value; + bool row_row = traits::is_elementwise::value; + bool row_column = traits::is_elementwise::value; + bool range_range = traits::is_elementwise::value; return LogicalVector::create( - _["vector"] = vector, - _["arith"] = arith, - _["math"] = math, - _["ifelse"] = if_else, - _["rev"] = reversed, - _["arith_rev"] = arith_rev, - _["head"] = first, - _["column"] = column + _["vector"] = vector, + _["arith"] = arith, + _["math"] = math, + _["ifelse"] = if_else, + _["rev"] = reversed, + _["arith_rev"] = arith_rev, + _["head"] = first, + _["column_vector"] = column_vector, + _["column_column"] = column_column, + _["column_row"] = column_row, + _["row_row"] = row_row, + _["row_column"] = row_column, + _["range_range"] = range_range ); } diff --git a/inst/tinytest/test_sugar.R b/inst/tinytest/test_sugar.R index 29fc99c40..b06844323 100644 --- a/inst/tinytest/test_sugar.R +++ b/inst/tinytest/test_sugar.R @@ -1746,12 +1746,22 @@ x <- function() c(a = 1, b = 2, c = 3) expect_equal(names(alias_rev(x())), names(x()), info = "x = rev(x) keeps names") expect_equal(names(alias_elementwise(x())), names(x()), info = "x = x * 2 + x keeps names") -## only vectors and elementwise expressions over them are written in place +## views of the target's own matrix can be read in place when they cover the +## same positions or disjoint ones (a column from columns, a row from rows) +m <- function() matrix(as.numeric(1:9), 3) +expect_equal(alias_column_scale(m()), m() * 2, info = "m(_, j) = m(_, j) * 2") +expect_equal(alias_row_scale(m()), m() * 2, info = "m(i, _) = m(i, _) * 2") +expect_equal(alias_row_from_column(m())[3, ], m()[, 1], info = "m(2, _) = m(_, 0) * 1") +expect_equal(alias_column_from_row(m())[, 3], m()[1, ], info = "m(_, 2) = m(0, _) * 1") + +## which expressions are written in place, depending on the target flags <- elementwise_flags(c(1, 2, 3), matrix(1, 2, 2)) expect_equal( flags, c(vector = TRUE, arith = TRUE, math = TRUE, ifelse = TRUE, - rev = FALSE, arith_rev = FALSE, head = FALSE, column = FALSE), + rev = FALSE, arith_rev = FALSE, head = FALSE, + column_vector = TRUE, column_column = TRUE, column_row = FALSE, + row_row = TRUE, row_column = FALSE, range_range = FALSE), info = "traits::is_elementwise" ) From 60f24be5398192f1322826fdcf1d710332640f44 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 12:06:49 -0700 Subject: [PATCH 05/11] keep sugar length-check errors out of line With the error path inlined, the compiler could no longer propagate constants into the loops following these checks (e.g. `m(_, j) = m(_, j) * 2.0` lost its constant multiplier and vectorized half as wide). --- inst/include/Rcpp/sugar/tools/check_sizes.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/inst/include/Rcpp/sugar/tools/check_sizes.h b/inst/include/Rcpp/sugar/tools/check_sizes.h index 0978d6847..988d09f4b 100644 --- a/inst/include/Rcpp/sugar/tools/check_sizes.h +++ b/inst/include/Rcpp/sugar/tools/check_sizes.h @@ -25,23 +25,32 @@ namespace Rcpp{ namespace sugar{ + // Kept out of line: inlining the error path keeps the compiler from + // optimizing the loops that follow these checks. +#if defined(__GNUC__) + __attribute__((noinline, cold)) +#endif + inline void NORET stop_sizes(const char* fmt, R_xlen_t n1, R_xlen_t n2) { + stop(fmt, n1, n2); + } + // Sugar doesn't recycle the way R does: the vectors an expression // combines must all have the same length. inline void check_sizes(R_xlen_t n1, R_xlen_t n2) { if (n1 != n2) - stop("sugar operands have different lengths (%d and %d)", n1, n2); + stop_sizes("sugar operands have different lengths (%d and %d)", n1, n2); } inline void check_sizes(R_xlen_t n1, R_xlen_t n2, R_xlen_t n3) { - if (n1 != n2 || n1 != n3) - stop("sugar operands have different lengths (%d, %d and %d)", n1, n2, n3); + check_sizes(n1, n2); + check_sizes(n1, n3); } // Likewise, a vector assigned into a range, row or column must have the // same length as that target. inline void check_assign_size(R_xlen_t target, R_xlen_t value) { if (target != value) - stop("cannot assign a vector of length %d to a target of length %d", value, target); + stop_sizes("cannot assign a vector of length %d to a target of length %d", value, target); } } // sugar From 878bea94f1a8a29e6045f4b63f8c766a08ecf735 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 12:07:57 -0700 Subject: [PATCH 06/11] document sugar operand lengths, lifetimes, and assignment --- ChangeLog | 27 +++++++++++ vignettes/rmd/Rcpp-sugar.Rmd | 89 +++++++++++++++++++++++++++++++++--- 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7ec6570b6..03db04c03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2026-09-30 Kevin Ushey + + * inst/include/Rcpp/traits/sugar_operand.h: New trait for how sugar + expressions hold their operands: vectors by reference, and nested + expressions and views by value, so stored expressions don't dangle + * inst/include/Rcpp/traits/is_elementwise.h: New trait for whether a + sugar expression can be written in place into storage it may read from + * inst/include/Rcpp/sugar/tools/check_sizes.h: New helpers checking that + sugar operands, and vectors assigned into views, have matching lengths + * inst/include/RcppCommon.h: Include the above + * inst/include/Rcpp/sugar/sugar_forward.h: Idem + * inst/include/Rcpp/sugar/: Hold operands via sugar_operand, declare + elementwise operands, and check operand lengths + * inst/include/Rcpp/stats/dpq/dpq.h: Idem + * inst/include/Rcpp/sugar/block/SugarBlock_3.h: Also fix the type of the + third operand + * inst/include/Rcpp/vector/Vector.h: Evaluate sugar expressions that + aren't elementwise before assigning them in place + * inst/include/Rcpp/vector/RangeIndexer.h: Idem, and check lengths + * inst/include/Rcpp/vector/MatrixColumn.h: Idem + * inst/include/Rcpp/vector/MatrixRow.h: Idem + * inst/include/Rcpp/vector/MatrixBase.h: Add a const get_ref() + * inst/tinytest/cpp/sugar_expressions.cpp: New tests + * inst/tinytest/test_sugar.R: Idem + * vignettes/rmd/Rcpp-sugar.Rmd: Document operand lengths, storing + expressions, and assignment + 2026-09-22 Iñaki Ucar * inst/include/Rcpp/sugar/matrix/col.h: Fix Col constructor using ncol() diff --git a/vignettes/rmd/Rcpp-sugar.Rmd b/vignettes/rmd/Rcpp-sugar.Rmd index 9384b78a9..e568880eb 100644 --- a/vignettes/rmd/Rcpp-sugar.Rmd +++ b/vignettes/rmd/Rcpp-sugar.Rmd @@ -191,7 +191,8 @@ arithmetic expression must be of the same type (for example they should be both The lhs and the rhs can either have the same size or one of them could be a primitive value of the appropriate type, for example adding a -`NumericVector` and a `double`. +`NumericVector` and a `double`. Unlike \proglang{R}, \sugar does not recycle +vectors of different sizes; see the section on expressions and assignment. ## Binary logical operators @@ -518,6 +519,69 @@ functions (\textsl{i.e.} you) should place an \code{RNGScope} at the appropriate level of your code. +# Expressions and assignment + +\sugar expressions are evaluated lazily: `x + y` builds an object describing +the computation, and its elements are only computed when the expression is +assigned to a vector or otherwise consumed, for example by `sum()`. + +## Operand lengths + +Unlike \proglang{R}, \sugar does not recycle: the vectors combined by an +expression must all have the same length, and an error is signalled +otherwise. Likewise, a vector assigned into a range, row or column (as in +`m(_, 0) = x`) must have the length of that target. Single values, like the +`2.0` in `x + 2.0`, can be combined with vectors of any length. + +## Storing expressions + +An expression holds the vectors it reads by reference, and any nested +expressions by value. It can be stored, for example in an `auto` variable, +and evaluated later, as long as the vectors it reads are still alive: + +```cpp +NumericVector x, y; + +// fine: x and y outlive e +auto e = x * 2.0 + y; +NumericVector z = e; +``` + +An expression reading from a temporary vector, however, has to be +evaluated in the statement that creates it: + +```cpp +// wrong: the clone is destroyed at the end of +// the statement, while e still refers to it +auto e = clone(x) + 1.0; + +// fine +NumericVector z = clone(x) + 1.0; +``` + +## Assignment + +Assigning an expression to an existing vector of the same length writes the +result into that vector's storage. As with any modification made through an +\pkg{Rcpp} vector, this is visible through every other reference to the same +\proglang{R} object, including the argument passed in from \proglang{R}: + +```cpp +// [[Rcpp::export]] +void twice(NumericVector x) { + // modifies the caller's vector + x = x * 2.0; +} +``` + +When the lengths differ, a new vector is allocated instead. + +An expression may read from the vector it is assigned to, as in +`x = rev(x)`. Expressions whose elements only depend on the corresponding +elements of their operands (arithmetic, comparisons, mathematical functions, +`ifelse()`, and so on) are written directly; others are first evaluated into +a temporary vector. + # Performance \label{sec:performance} @@ -658,7 +722,7 @@ public: RESULT_R_TYPE>::type STORAGE; Sapply(const VEC& vec_, Function fun_) : - vec(vec_), fun(fun_){} + vec(vec_.get_ref()), fun(fun_){} inline STORAGE operator[]( int i ) const { return converter_type::get(fun(vec[i])); @@ -669,7 +733,7 @@ public: } private: - const VEC& vec; + typename Rcpp::traits::sugar_operand::type vec; Function fun; }; @@ -801,18 +865,22 @@ is the manifestation of the _CRTP_. The constructor of the `Sapply` class template is straightforward, it -simply consists of holding the reference to the input expression and the -function. +simply consists of holding the input expression and the function. ```cpp Sapply(const VEC& vec_, Function fun_): - vec(vec_), fun(fun_){} + vec(vec_.get_ref()), fun(fun_){} private: - const VEC& vec; + typename Rcpp::traits::sugar_operand::type vec; Function fun; ``` +The input is held through `sugar_operand`: by reference when it is a vector, +and by value when it is itself a \sugar expression. Those are typically +temporaries, so holding them by reference would leave `Sapply` referring to +destroyed objects once the statement that created it ends. + ### Implementation The indexing operator and the `size` member function is what @@ -830,6 +898,13 @@ inline int size() const { } ``` +Expressions whose $i^{\text{th}}$ element only depends on the +$i^{\text{th}}$ elements of their operands can say so by declaring +`typedef Rcpp::traits::elementwise_operands rcpp_elementwise`, which +lets them be written in place when assigned to one of those operands. +`Sapply` does not, since the function it applies may read any element of +the vector being assigned to. + # Summary TBD From 3292c48363fa4da622846b6040dd31226e013b4a Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 12:09:39 -0700 Subject: [PATCH 07/11] update NEWS --- inst/NEWS.Rd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 0bac0eee9..800ba3dd0 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -27,6 +27,10 @@ warnings (Iñaki in \ghpr{1508} closing \ghit{1497}) \item The \code{col} constructor now uses \code{nrow} in an initialization (Iñaki in \ghpr{1509}) + \item Sugar expressions hold nested expressions by value so they can be + stored, evaluate expressions that may read the target before assigning + them in place, and signal an error for operands of different lengths + (Kevin in \ghpr{1513} closing \ghit{1512}) } \item Changes in Rcpp Documentation: \itemize{ From dcca2a1952a8be177403895302b85ffcb0e48093 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 12:22:27 -0700 Subject: [PATCH 08/11] fix !, &&, and || on single logical results None of `!all(x)`, `all(x) && any(y)`, `all(x) || any(y)`, `all(x) && true` or `all(x) || true` compiled: the combinators called the non-const get() through const references, the && and || overloads for two results declared their second parameter with the first one's template arguments (so they could never be deduced), and Or_SingleLogicalResult_bool named the And class as its CRTP base. The combinators now hold their operands by value, like other sugar expressions, and the general && and || follow R's three-valued logic (NA && FALSE is FALSE, NA || TRUE is TRUE). --- ChangeLog | 8 +++ inst/NEWS.Rd | 3 + .../Rcpp/sugar/logical/SingleLogicalResult.h | 8 +++ inst/include/Rcpp/sugar/logical/and.h | 45 ++++++++------ inst/include/Rcpp/sugar/logical/not.h | 6 +- inst/include/Rcpp/sugar/logical/or.h | 47 ++++++++------ inst/tinytest/cpp/sugar_expressions.cpp | 62 +++++++++++++++++++ inst/tinytest/test_sugar.R | 26 ++++++++ 8 files changed, 164 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03db04c03..9dfd6f1e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,14 @@ * inst/include/Rcpp/stats/dpq/dpq.h: Idem * inst/include/Rcpp/sugar/block/SugarBlock_3.h: Also fix the type of the third operand + * inst/include/Rcpp/sugar/logical/and.h: Fix operator&& on two single + logical results, hold their operands by value, and make NA && FALSE + return FALSE + * inst/include/Rcpp/sugar/logical/or.h: Idem for operator||, making + NA || TRUE return TRUE, and fix the base class of Or_SingleLogicalResult_bool + * inst/include/Rcpp/sugar/logical/not.h: Hold the operand of operator! + by value + * inst/include/Rcpp/sugar/logical/SingleLogicalResult.h: Add get_ref() * inst/include/Rcpp/vector/Vector.h: Evaluate sugar expressions that aren't elementwise before assigning them in place * inst/include/Rcpp/vector/RangeIndexer.h: Idem, and check lengths diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 800ba3dd0..b7ee67de3 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -31,6 +31,9 @@ stored, evaluate expressions that may read the target before assigning them in place, and signal an error for operands of different lengths (Kevin in \ghpr{1513} closing \ghit{1512}) + \item The sugar operators \code{!}, \code{&&} and \code{||} on single + logical results such as \code{all()} compile again, and follow R's + handling of \code{NA} (Kevin in \ghpr{1513}) } \item Changes in Rcpp Documentation: \itemize{ diff --git a/inst/include/Rcpp/sugar/logical/SingleLogicalResult.h b/inst/include/Rcpp/sugar/logical/SingleLogicalResult.h index fe0aad570..4dd5730ea 100644 --- a/inst/include/Rcpp/sugar/logical/SingleLogicalResult.h +++ b/inst/include/Rcpp/sugar/logical/SingleLogicalResult.h @@ -45,6 +45,14 @@ class SingleLogicalResult { SingleLogicalResult() : result(UNRESOLVED) {} ; + T& get_ref(){ + return static_cast(*this) ; + } + + const T& get_ref() const { + return static_cast(*this) ; + } + void apply(){ if( result == UNRESOLVED ){ static_cast(*this).apply() ; diff --git a/inst/include/Rcpp/sugar/logical/and.h b/inst/include/Rcpp/sugar/logical/and.h index dcb4bd1b8..f36763ccd 100644 --- a/inst/include/Rcpp/sugar/logical/and.h +++ b/inst/include/Rcpp/sugar/logical/and.h @@ -41,22 +41,29 @@ public SingleLogicalResult< > BASE ; And_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ int left = lhs.get() ; - if( Rcpp::traits::is_na( left ) ){ - BASE::set( left ) ; - } else if( left == FALSE ){ + if( left == FALSE ){ BASE::set( FALSE ) ; + return ; + } + + // NA && FALSE is FALSE + int right = rhs.get() ; + if( Rcpp::traits::is_na( left ) && right != FALSE ){ + BASE::set( left ) ; } else { - BASE::set( rhs.get() ) ; + BASE::set( right ) ; } } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + // by value, since these are usually temporaries, and non-const, since + // evaluating them caches their result + LHS_T lhs ; + RHS_T rhs ; } ; @@ -77,7 +84,7 @@ public SingleLogicalResult< > BASE ; And_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ // here we know rhs does not have NA, so we start with the rhs @@ -90,8 +97,8 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + LHS_T lhs ; + RHS_T rhs ; } ; @@ -113,7 +120,7 @@ public SingleLogicalResult< > BASE ; And_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ // here we know lhs does not have NA, so we start with the rhs @@ -126,8 +133,8 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + LHS_T lhs ; + RHS_T rhs ; } ; @@ -148,7 +155,7 @@ public SingleLogicalResult< > BASE ; And_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ int left = lhs.get() ; @@ -160,8 +167,8 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + LHS_T lhs ; + RHS_T rhs ; } ; @@ -182,7 +189,7 @@ public SingleLogicalResult< > BASE ; And_SingleLogicalResult_bool( const LHS_TYPE& lhs_, bool rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_){} ; inline void apply(){ if( !rhs ){ @@ -193,7 +200,7 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; + LHS_T lhs ; bool rhs ; } ; @@ -299,7 +306,7 @@ template inline Rcpp::sugar::And_SingleLogicalResult_SingleLogicalResult operator&&( const Rcpp::sugar::SingleLogicalResult& lhs, - const Rcpp::sugar::SingleLogicalResult& rhs + const Rcpp::sugar::SingleLogicalResult& rhs ){ return Rcpp::sugar::And_SingleLogicalResult_SingleLogicalResult( lhs, rhs ) ; } diff --git a/inst/include/Rcpp/sugar/logical/not.h b/inst/include/Rcpp/sugar/logical/not.h index db63cd6e6..d975d55c1 100644 --- a/inst/include/Rcpp/sugar/logical/not.h +++ b/inst/include/Rcpp/sugar/logical/not.h @@ -43,14 +43,16 @@ class Negate_SingleLogicalResult : public SingleLogicalResult TYPE ; typedef SingleLogicalResult > BASE ; - Negate_SingleLogicalResult( const TYPE& orig_ ) : orig(orig_) {} + Negate_SingleLogicalResult( const TYPE& orig_ ) : orig(orig_.get_ref()) {} inline void apply(){ BASE::set( negate::apply( orig.get() ) ); } private: - const TYPE& orig ; + // by value, since it is usually a temporary, and non-const, since + // evaluating it caches its result + T orig ; } ; diff --git a/inst/include/Rcpp/sugar/logical/or.h b/inst/include/Rcpp/sugar/logical/or.h index c85d3b390..4e9f610ea 100644 --- a/inst/include/Rcpp/sugar/logical/or.h +++ b/inst/include/Rcpp/sugar/logical/or.h @@ -41,22 +41,29 @@ public SingleLogicalResult< > BASE ; Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ int left = lhs.get() ; - if( Rcpp::traits::is_na( left ) ){ - BASE::set( left ) ; - } else if( left == TRUE ){ + if( left == TRUE ){ BASE::set( TRUE ) ; + return ; + } + + // NA || TRUE is TRUE + int right = rhs.get() ; + if( Rcpp::traits::is_na( left ) && right != TRUE ){ + BASE::set( left ) ; } else { - BASE::set( rhs.get() ) ; + BASE::set( right ) ; } } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + // by value, since these are usually temporaries, and non-const, since + // evaluating them caches their result + LHS_T lhs ; + RHS_T rhs ; } ; @@ -77,7 +84,7 @@ public SingleLogicalResult< > BASE ; Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ // here we know rhs does not have NA, so we start with the rhs @@ -90,8 +97,8 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + LHS_T lhs ; + RHS_T rhs ; } ; @@ -113,7 +120,7 @@ public SingleLogicalResult< > BASE ; Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ // here we know lhs does not have NA, so we start with the rhs @@ -126,8 +133,8 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + LHS_T lhs ; + RHS_T rhs ; } ; @@ -148,7 +155,7 @@ public SingleLogicalResult< > BASE ; Or_SingleLogicalResult_SingleLogicalResult( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} ; inline void apply(){ int left = lhs.get() ; @@ -160,8 +167,8 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; - const RHS_TYPE& rhs ; + LHS_T lhs ; + RHS_T rhs ; } ; @@ -170,7 +177,7 @@ template class Or_SingleLogicalResult_bool : public SingleLogicalResult< LHS_NA , - And_SingleLogicalResult_bool + Or_SingleLogicalResult_bool > { public: @@ -181,7 +188,7 @@ public SingleLogicalResult< > BASE ; Or_SingleLogicalResult_bool( const LHS_TYPE& lhs_, bool rhs_) : - lhs(lhs_), rhs(rhs_){} ; + lhs(lhs_.get_ref()), rhs(rhs_){} ; inline void apply(){ if( rhs ){ @@ -192,7 +199,7 @@ public SingleLogicalResult< } private: - const LHS_TYPE& lhs ; + LHS_T lhs ; bool rhs ; } ; @@ -298,7 +305,7 @@ template inline Rcpp::sugar::Or_SingleLogicalResult_SingleLogicalResult operator||( const Rcpp::sugar::SingleLogicalResult& lhs, - const Rcpp::sugar::SingleLogicalResult& rhs + const Rcpp::sugar::SingleLogicalResult& rhs ){ return Rcpp::sugar::Or_SingleLogicalResult_SingleLogicalResult( lhs, rhs ) ; } diff --git a/inst/tinytest/cpp/sugar_expressions.cpp b/inst/tinytest/cpp/sugar_expressions.cpp index 028e4fd71..35cdde607 100644 --- a/inst/tinytest/cpp/sugar_expressions.cpp +++ b/inst/tinytest/cpp/sugar_expressions.cpp @@ -288,3 +288,65 @@ NumericMatrix length_row(NumericMatrix m, NumericVector y) { m(0, _) = y; return m; } + +// [[Rcpp::export]] +SEXP single_and(LogicalVector a, LogicalVector b) { + return all(a) && all(b); +} + +// [[Rcpp::export]] +SEXP single_or(LogicalVector a, LogicalVector b) { + return all(a) || all(b); +} + +// [[Rcpp::export]] +SEXP single_not(LogicalVector a) { + return !all(a); +} + +// [[Rcpp::export]] +SEXP single_and_nona_lhs(LogicalVector a, LogicalVector b) { + return all(noNA(a)) && all(b); +} + +// [[Rcpp::export]] +SEXP single_and_nona_rhs(LogicalVector a, LogicalVector b) { + return all(a) && all(noNA(b)); +} + +// [[Rcpp::export]] +SEXP single_and_nona_both(LogicalVector a, LogicalVector b) { + return all(noNA(a)) && all(noNA(b)); +} + +// [[Rcpp::export]] +SEXP single_or_nona_lhs(LogicalVector a, LogicalVector b) { + return all(noNA(a)) || all(b); +} + +// [[Rcpp::export]] +SEXP single_or_nona_rhs(LogicalVector a, LogicalVector b) { + return all(a) || all(noNA(b)); +} + +// [[Rcpp::export]] +SEXP single_or_nona_both(LogicalVector a, LogicalVector b) { + return all(noNA(a)) || all(noNA(b)); +} + +// [[Rcpp::export]] +SEXP single_and_bool(LogicalVector a, bool b) { + return all(a) && b; +} + +// [[Rcpp::export]] +SEXP single_or_bool(LogicalVector a, bool b) { + return b || all(a); +} + +// [[Rcpp::export]] +SEXP single_stored(LogicalVector a, LogicalVector b) { + auto e = !(all(a) && any(b)); + clobber_stack(); + return e; +} diff --git a/inst/tinytest/test_sugar.R b/inst/tinytest/test_sugar.R index b06844323..a1f120a46 100644 --- a/inst/tinytest/test_sugar.R +++ b/inst/tinytest/test_sugar.R @@ -1782,3 +1782,29 @@ expect_error(length_range(c(1, 2, 3, 4, 5), c(7, 8)), "cannot assign", info = "x expect_error(length_range(c(1, 2, 3, 4, 5), c(6, 7, 8, 9)), "cannot assign", info = "x[0:2] = ") expect_error(length_column(matrix(1, 3, 2), c(7, 8)), "cannot assign", info = "m(_, 0) = ") expect_error(length_row(matrix(1, 3, 2), c(7, 8, 9)), "cannot assign", info = "m(0, _) = ") + +## &&, || and ! on single logical results (e.g. all(), any()) follow R's +## three-valued logic +vals <- c(TRUE, FALSE, NA) +for (a in vals) { + expect_identical(single_not(a), !a, info = sprintf("!%s", a)) + for (b in vals) { + expect_identical(single_and(a, b), a && b, info = sprintf("%s && %s", a, b)) + expect_identical(single_or(a, b), a || b, info = sprintf("%s || %s", a, b)) + if (!is.na(a)) { + expect_identical(single_and_nona_lhs(a, b), a && b, info = sprintf("noNA(%s) && %s", a, b)) + expect_identical(single_or_nona_lhs(a, b), a || b, info = sprintf("noNA(%s) || %s", a, b)) + } + if (!is.na(b)) { + expect_identical(single_and_nona_rhs(a, b), a && b, info = sprintf("%s && noNA(%s)", a, b)) + expect_identical(single_or_nona_rhs(a, b), a || b, info = sprintf("%s || noNA(%s)", a, b)) + expect_identical(single_and_bool(a, b), a && b, info = sprintf("%s && ", a, b)) + expect_identical(single_or_bool(a, b), b || a, info = sprintf(" || %s", b, a)) + } + if (!is.na(a) && !is.na(b)) { + expect_identical(single_and_nona_both(a, b), a && b, info = sprintf("noNA(%s) && noNA(%s)", a, b)) + expect_identical(single_or_nona_both(a, b), a || b, info = sprintf("noNA(%s) || noNA(%s)", a, b)) + } + } +} +expect_identical(single_stored(c(TRUE, TRUE), c(FALSE, TRUE)), FALSE, info = "auto: !(all(a) && any(b))") From e03c2ed4e31cb9e9c977eabd76c2f6a48a7ceaea Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 12:22:43 -0700 Subject: [PATCH 09/11] update NEWS --- inst/NEWS.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index b7ee67de3..88d33462a 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -32,7 +32,7 @@ them in place, and signal an error for operands of different lengths (Kevin in \ghpr{1513} closing \ghit{1512}) \item The sugar operators \code{!}, \code{&&} and \code{||} on single - logical results such as \code{all()} compile again, and follow R's + logical results such as \code{all()} now compile, and follow R's handling of \code{NA} (Kevin in \ghpr{1513}) } \item Changes in Rcpp Documentation: From 32b70a4b8c34abc5159d61e8cf92d4643c17d811 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 13:05:46 -0700 Subject: [PATCH 10/11] route range-to-range assignment through the aliasing checks Also mark Range as elementwise, include sugar_operand.h from is_elementwise.h, and drop stale FIXME comments in ifelse.h. --- inst/include/Rcpp/sugar/Range.h | 2 ++ inst/include/Rcpp/sugar/functions/ifelse.h | 8 ++------ inst/include/Rcpp/traits/is_elementwise.h | 2 ++ inst/include/Rcpp/vector/RangeIndexer.h | 9 ++++++++ inst/tinytest/cpp/sugar_expressions.cpp | 24 +++++++++++++++++++++- inst/tinytest/test_sugar.R | 5 ++++- 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/inst/include/Rcpp/sugar/Range.h b/inst/include/Rcpp/sugar/Range.h index 08da6d1c4..8042f3845 100644 --- a/inst/include/Rcpp/sugar/Range.h +++ b/inst/include/Rcpp/sugar/Range.h @@ -27,6 +27,8 @@ namespace Rcpp{ class Range : public VectorBase{ public: + typedef traits::elementwise_operands<> rcpp_elementwise ; + Range( R_xlen_t start_, R_xlen_t end__ ) : start(start_), end_(end__){ if( start_ > end__ ){ throw std::range_error( "upper value must be greater than lower value" ) ; diff --git a/inst/include/Rcpp/sugar/functions/ifelse.h b/inst/include/Rcpp/sugar/functions/ifelse.h index 0b2de8f2b..0a0f91803 100644 --- a/inst/include/Rcpp/sugar/functions/ifelse.h +++ b/inst/include/Rcpp/sugar/functions/ifelse.h @@ -287,9 +287,7 @@ class IfElse_Primitive_Primitive : public VectorBase< typedef Rcpp::traits::elementwise_operands< COND_TYPE > rcpp_elementwise ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : - cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { - /* FIXME : cond, lhs and rhs must all have the same size */ - } + cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) {} inline STORAGE operator[]( R_xlen_t i ) const { int x = cond[i] ; @@ -321,9 +319,7 @@ class IfElse_Primitive_Primitive : public VectorBase< typedef Rcpp::traits::elementwise_operands< COND_TYPE > rcpp_elementwise ; IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) : - cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) { - /* FIXME : cond, lhs and rhs must all have the same size */ - } + cond(cond_.get_ref()), lhs(lhs_), rhs(rhs_) {} inline STORAGE operator[]( R_xlen_t i ) const { return cond[i] ? lhs : rhs ; diff --git a/inst/include/Rcpp/traits/is_elementwise.h b/inst/include/Rcpp/traits/is_elementwise.h index 701a69a58..7be36fd65 100644 --- a/inst/include/Rcpp/traits/is_elementwise.h +++ b/inst/include/Rcpp/traits/is_elementwise.h @@ -23,6 +23,8 @@ #ifndef Rcpp__traits__is_elementwise_h #define Rcpp__traits__is_elementwise_h +#include + namespace Rcpp{ namespace traits{ diff --git a/inst/include/Rcpp/vector/RangeIndexer.h b/inst/include/Rcpp/vector/RangeIndexer.h index 4a8e57e74..ec2a000df 100644 --- a/inst/include/Rcpp/vector/RangeIndexer.h +++ b/inst/include/Rcpp/vector/RangeIndexer.h @@ -67,11 +67,20 @@ class RangeIndexer : public VectorBase RangeIndexer( VECTOR& vec_, const Rcpp::Range& range_) : start(vec_.begin() + range_.get_start() ), size_( range_.size() ) {} + RangeIndexer( const RangeIndexer& other ) : + start(other.start), size_(other.size_) {} + template RangeIndexer& operator=( const Rcpp::VectorBase& x){ UNROLL_LOOP(=) } + // without this, assigning one range to another would use the implicit + // copy assignment, which rebinds this range instead of copying elements + RangeIndexer& operator=( const RangeIndexer& x ){ + return operator=( static_cast&>(x) ) ; + } + template RangeIndexer& operator+=( const Rcpp::VectorBase& x){ UNROLL_LOOP(+=) diff --git a/inst/tinytest/cpp/sugar_expressions.cpp b/inst/tinytest/cpp/sugar_expressions.cpp index 35cdde607..e7ca5635b 100644 --- a/inst/tinytest/cpp/sugar_expressions.cpp +++ b/inst/tinytest/cpp/sugar_expressions.cpp @@ -149,6 +149,20 @@ NumericVector alias_range_shift(NumericVector x) { return x; } +// [[Rcpp::export]] +NumericVector alias_range_range(NumericVector x) { + R_xlen_t n = x.size(); + x[Range(1, n - 1)] = x[Range(0, n - 2)]; + return x; +} + +// [[Rcpp::export]] +NumericVector alias_range_range_add(NumericVector x) { + R_xlen_t n = x.size(); + x[Range(1, n - 1)] += x[Range(0, n - 2)]; + return x; +} + // [[Rcpp::export]] NumericVector alias_range_rev(NumericVector x) { R_xlen_t n = x.size(); @@ -223,6 +237,7 @@ LogicalVector elementwise_flags(NumericVector x, NumericMatrix m) { bool row_row = traits::is_elementwise::value; bool row_column = traits::is_elementwise::value; bool range_range = traits::is_elementwise::value; + bool sequence = traits::is_elementwise::value; return LogicalVector::create( _["vector"] = vector, @@ -237,7 +252,8 @@ LogicalVector elementwise_flags(NumericVector x, NumericMatrix m) { _["column_row"] = column_row, _["row_row"] = row_row, _["row_column"] = row_column, - _["range_range"] = range_range + _["range_range"] = range_range, + _["seq"] = sequence ); } @@ -277,6 +293,12 @@ NumericVector length_range(NumericVector x, NumericVector y) { return x; } +// [[Rcpp::export]] +NumericVector length_range_range(NumericVector x) { + x[Range(0, 1)] = x[Range(0, 3)]; + return x; +} + // [[Rcpp::export]] NumericMatrix length_column(NumericMatrix m, NumericVector y) { m(_, 0) = y; diff --git a/inst/tinytest/test_sugar.R b/inst/tinytest/test_sugar.R index a1f120a46..66b283f77 100644 --- a/inst/tinytest/test_sugar.R +++ b/inst/tinytest/test_sugar.R @@ -1734,6 +1734,8 @@ expect_equal(alias_mixed(x()), x() + rev(x()), info = "x = x + rev(x)") expect_equal(alias_sapply(x()), x() - x()[1], info = "x = sapply(x, )") expect_equal(alias_elementwise(x()), x() * 2 + x(), info = "x = x * 2 + x") expect_equal(alias_range_shift(x()), c(1, 1, 2, 3, 4), info = "x[1:n-1] = head(x, n-1)") +expect_equal(alias_range_range(x()), c(1, 1, 2, 3, 4), info = "x[1:n-1] = x[0:n-2]") +expect_equal(alias_range_range_add(x()), c(1, 3, 5, 7, 9), info = "x[1:n-1] += x[0:n-2]") expect_equal(alias_range_rev(x()), rev(x()), info = "x[0:n-1] = rev(x)") expect_equal(alias_range_add_rev(x()), x() + rev(x()), info = "x[0:n-1] += rev(x)") m <- function() matrix(c(1, 2, 3, 4, 5, 6), 3) @@ -1761,7 +1763,7 @@ expect_equal( c(vector = TRUE, arith = TRUE, math = TRUE, ifelse = TRUE, rev = FALSE, arith_rev = FALSE, head = FALSE, column_vector = TRUE, column_column = TRUE, column_row = FALSE, - row_row = TRUE, row_column = FALSE, range_range = FALSE), + row_row = TRUE, row_column = FALSE, range_range = FALSE, seq = TRUE), info = "traits::is_elementwise" ) @@ -1780,6 +1782,7 @@ expect_error(length_ifelse(c(TRUE, FALSE), c(1, 2), c(1, 2, 3)), "different leng expect_equal(length_range(c(1, 2, 3, 4, 5), c(7, 8, 9)), c(7, 8, 9, 4, 5), info = "x[0:2] = y") expect_error(length_range(c(1, 2, 3, 4, 5), c(7, 8)), "cannot assign", info = "x[0:2] = ") expect_error(length_range(c(1, 2, 3, 4, 5), c(6, 7, 8, 9)), "cannot assign", info = "x[0:2] = ") +expect_error(length_range_range(c(1, 2, 3, 4, 5)), "cannot assign", info = "x[0:1] = x[0:3]") expect_error(length_column(matrix(1, 3, 2), c(7, 8)), "cannot assign", info = "m(_, 0) = ") expect_error(length_row(matrix(1, 3, 2), c(7, 8, 9)), "cannot assign", info = "m(0, _) = ") From d4cbe584f9a3c5bc76cbcce1654b3161e2be32d4 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Wed, 30 Sep 2026 13:05:47 -0700 Subject: [PATCH 11/11] read subset elements before writing when both index the same vector --- inst/NEWS.Rd | 7 ++++++- inst/include/Rcpp/vector/Subsetter.h | 22 +++++++++++++++++----- inst/tinytest/cpp/Subset.cpp | 25 +++++++++++++++++++++++++ inst/tinytest/test_subset.R | 7 +++++++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 88d33462a..0666ec7ea 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -30,7 +30,12 @@ \item Sugar expressions hold nested expressions by value so they can be stored, evaluate expressions that may read the target before assigning them in place, and signal an error for operands of different lengths - (Kevin in \ghpr{1513} closing \ghit{1512}) + (Kevin in \ghpr{1513} closing \ghit{1512}). Same-length assignment + of an expression that is not elementwise, such as \code{x = rev(x)}, + now goes through a temporary vector. + \item Assignment between overlapping subsets of the same vector, as in + \code{x[i] = x[j]}, reads the source elements before writing (Kevin in + \ghpr{1513}) \item The sugar operators \code{!}, \code{&&} and \code{||} on single logical results such as \code{all()} now compile, and follow R's handling of \code{NA} (Kevin in \ghpr{1513}) diff --git a/inst/include/Rcpp/vector/Subsetter.h b/inst/include/Rcpp/vector/Subsetter.h index 8f97561a7..53233f1b6 100644 --- a/inst/include/Rcpp/vector/Subsetter.h +++ b/inst/include/Rcpp/vector/Subsetter.h @@ -110,16 +110,28 @@ class SubsetProxy { SubsetProxy& operator=(const SubsetProxy& other) { if (other.indices_n == 1) { + // a single source element is only ever overwritten with itself for (R_xlen_t i=0; i < indices_n; ++i) { lhs[ indices[i] ] = other.lhs[other.indices[0]]; } } - else if (indices_n == other.indices_n) { - for (R_xlen_t i=0; i < indices_n; ++i) - lhs[ indices[i] ] = other.lhs[other.indices[i]]; + else if (indices_n != other.indices_n) { + stop("index error"); + } + else if (lhs.get__() == other.lhs.get__()) { + // both subsets index the same vector, so a source element may + // be overwritten before it is read; copy the source elements + // first + Vector tmp = no_init(other.indices_n); + for (R_xlen_t i=0; i < other.indices_n; ++i) { + tmp[i] = other.lhs[other.indices[i]]; } + return *this = tmp; + } else { - stop("index error"); + for (R_xlen_t i=0; i < indices_n; ++i) { + lhs[ indices[i] ] = other.lhs[other.indices[i]]; + } } return *this; } @@ -238,7 +250,7 @@ class SubsetProxy { Vector operator __OPERATOR__ ( \ const SubsetProxy& other) { \ - Vector result(indices_n); \ + Vector result = no_init(indices_n); \ if (other.indices_n == 1) { \ for (R_xlen_t i = 0; i < indices_n; ++i) \ result[i] = lhs[indices[i]] __OPERATOR__ other.lhs[other.indices[0]]; \ diff --git a/inst/tinytest/cpp/Subset.cpp b/inst/tinytest/cpp/Subset.cpp index d8bd0d620..fc7f2cb72 100644 --- a/inst/tinytest/cpp/Subset.cpp +++ b/inst/tinytest/cpp/Subset.cpp @@ -102,6 +102,31 @@ NumericVector subset_assign_vector_size_1(NumericVector x, int i) { return x; } +// [[Rcpp::export]] +NumericVector subset_assign_alias(NumericVector x) { + // overlapping subsets of the same vector + x[IntegerVector::create(1, 2)] = x[IntegerVector::create(0, 1)]; + return x; +} + +// [[Rcpp::export]] +CharacterVector subset_assign_alias_string(CharacterVector x) { + x[IntegerVector::create(1, 2)] = x[IntegerVector::create(0, 1)]; + return x; +} + +// [[Rcpp::export]] +NumericVector subset_assign_alias_disjoint(NumericVector x) { + x[IntegerVector::create(0, 1)] = x[IntegerVector::create(2, 3)]; + return x; +} + +// [[Rcpp::export]] +NumericVector subset_assign_alias_single(NumericVector x) { + x[IntegerVector::create(0, 1, 2)] = x[IntegerVector::create(2)]; + return x; +} + // [[Rcpp::export]] NumericVector subset_sugar_add(NumericVector x, IntegerVector y) { diff --git a/inst/tinytest/test_subset.R b/inst/tinytest/test_subset.R index 526a9f131..d7e6f09a2 100644 --- a/inst/tinytest/test_subset.R +++ b/inst/tinytest/test_subset.R @@ -65,6 +65,13 @@ expect_error(subset_assign_subset5(1:6), info = "index error") expect_identical(subset_assign_vector_size_1(1:6,7), c(7,7,7,4,5,6)) +## assigning between subsets of the same vector reads every source element +## before any is overwritten +expect_identical(subset_assign_alias(c(1, 2, 3)), c(1, 1, 2), info = "x[1:2] = x[0:1]") +expect_identical(subset_assign_alias_string(c("a", "b", "c")), c("a", "a", "b"), info = "x[1:2] = x[0:1], strings") +expect_identical(subset_assign_alias_disjoint(c(1, 2, 3, 4)), c(3, 4, 3, 4), info = "x[0:1] = x[2:3]") +expect_identical(subset_assign_alias_single(c(1, 2, 3)), c(3, 3, 3), info = "x[0:2] = x[2]") + x <- rnorm(10) y <- sample(10, 5) expect_identical(subset_sugar_add(x, y - 1L), x[y] + x[y])