Skip to content
Open
20 changes: 20 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
2026-02-26 Iñaki Ucar <iucar@fedoraproject.org>

* inst/include/Rcpp/sugar/tools/safe_math.h: New header implementing safe
versions of add/sub/mul operations for integral types
* inst/include/Rcpp/sugar/sugar.h: Includes the previous header

* inst/include/Rcpp/sugar/functions/cumprod.h: Use the previous operations
* inst/include/Rcpp/sugar/functions/cumsum.h: Idem
* inst/include/Rcpp/sugar/functions/diff.h: Idem
* inst/include/Rcpp/sugar/functions/rowSums.h: Idem
* inst/include/Rcpp/sugar/functions/sum.h: Idem
* inst/include/Rcpp/sugar/operators/minus.h: Idem
* inst/include/Rcpp/sugar/operators/plus.h: Idem
* inst/include/Rcpp/sugar/operators/times.h: Idem

* inst/tinytest/test_sugar.R: New tests covering the new operations
* inst/tinytest/cpp/sugar.cpp: Idem
* inst/tinytest/cpp/sugar_safe_math.cpp: Idem
* inst/tinytest/cpp/sugar_safe_math_fallback.cpp: Idem

2026-02-17 Dirk Eddelbuettel <edd@debian.org>

* DESCRIPTION (Version, Date): Roll micro version and date
Expand Down
13 changes: 7 additions & 6 deletions inst/include/Rcpp/sugar/functions/cumprod.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
//
// cumsum.h: Rcpp R/C++ interface class library -- cumsum
//
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
// Copyright (C) 2010 - 2025 Dirk Eddelbuettel and Romain Francois
// Copyright (C) 2026 Dirk Eddelbuettel, Romain Francois and Iñaki Ucar
//
// This file is part of Rcpp.
//
Expand Down Expand Up @@ -33,23 +34,23 @@ class Cumprod : public Lazy< Rcpp::Vector<RTYPE>, Cumprod<RTYPE, NA, T> > {
typedef Rcpp::Vector<RTYPE> VECTOR;

Cumprod(const VEC_TYPE& object_) : object(object_) {}

VECTOR get() const {
R_xlen_t n = object.size();
VECTOR result(n, Rcpp::traits::get_na<RTYPE>());
STORAGE current = object[0];

if (Rcpp::traits::is_na<RTYPE>(current)) return result;
result[0] = current;
for (R_xlen_t i = 1; i < n; i++) {
current = object[i];
if (Rcpp::traits::is_na<RTYPE>(current)) return result;
result[i] = result[i-1] * current;
result[i] = RCPP_SAFE_MUL(result[i-1], current);
}
return result ;
}
private:
const VEC_TYPE& object;
const VEC_TYPE& object;
};

} // sugar
Expand All @@ -72,5 +73,5 @@ inline sugar::Cumprod<CPLXSXP, NA, T> cumprod(const VectorBase<CPLXSXP, NA, T>&


} // Rcpp
#endif // Rcpp__sugar__cumprod_h
#endif // Rcpp__sugar__cumprod_h

5 changes: 3 additions & 2 deletions inst/include/Rcpp/sugar/functions/cumsum.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
//
// cumsum.h: Rcpp R/C++ interface class library -- cumsum
//
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
// Copyright (C) 2010 - 2025 Dirk Eddelbuettel and Romain Francois
// Copyright (C) 2026 Dirk Eddelbuettel, Romain Francois and Iñaki Ucar
//
// This file is part of Rcpp.
//
Expand Down Expand Up @@ -45,7 +46,7 @@ class Cumsum : public Lazy< Rcpp::Vector<RTYPE> , Cumsum<RTYPE,NA,T> > {
current = object[i] ;
if( Rcpp::traits::is_na<RTYPE>(current) )
return result ;
result[i] = result[i-1] + current ;
result[i] = RCPP_SAFE_ADD(result[i-1], current);
}
return result ;
}
Expand Down
11 changes: 6 additions & 5 deletions inst/include/Rcpp/sugar/functions/diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
//
// diff.h: Rcpp R/C++ interface class library -- diff
//
// Copyright (C) 2010 - 2013 Dirk Eddelbuettel and Romain Francois
// Copyright (C) 2010 - 2025 Dirk Eddelbuettel and Romain Francois
// Copyright (C) 2026 Dirk Eddelbuettel, Romain Francois and Iñaki Ucar
//
// This file is part of Rcpp.
//
Expand Down Expand Up @@ -51,7 +52,7 @@ class Diff : public Rcpp::VectorBase< RTYPE, LHS_NA , Diff<RTYPE,LHS_NA,LHS_T> >
set_previous(i+1, y ) ;
return traits::get_na<RTYPE>() ; // NA
}
STORAGE res = y - previous ;
STORAGE res = RCPP_SAFE_SUB(y, previous);
set_previous( i+1, y) ;
return res ;
}
Expand Down Expand Up @@ -81,7 +82,7 @@ class Diff<REALSXP, LHS_NA, LHS_T> : public Rcpp::VectorBase< REALSXP, LHS_NA, D
inline double operator[]( R_xlen_t i ) const {
double y = lhs[i+1] ;
if( previous_index != i ) previous = lhs[i] ;
double res = y - previous ;
double res = RCPP_SAFE_SUB(y, previous);
previous = y ;
previous_index = i+1 ;
return res ;
Expand All @@ -105,10 +106,10 @@ class Diff<RTYPE,false,LHS_T> : public Rcpp::VectorBase< RTYPE, false , Diff<RTY
inline STORAGE operator[]( R_xlen_t i ) const {
STORAGE y = lhs[i+1] ;
if( previous_index != i ) previous = lhs[i] ;
STORAGE diff = y - previous ;
STORAGE diff = RCPP_SAFE_SUB(y, previous);
previous = y ;
previous_index = i+1 ;
return y - previous ;
return RCPP_SAFE_SUB(y, previous);
}
inline R_xlen_t size() const { return lhs.size() - 1 ; }

Expand Down
Loading