Skip to content

Commit a8ce757

Browse files
committed
fix operators/times.h
1 parent 6e012f5 commit a8ce757

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

inst/include/Rcpp/sugar/operators/times.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
//
33
// times.h: Rcpp R/C++ interface class library -- operator*
44
//
5-
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
5+
// Copyright (C) 2010 - 2025 Dirk Eddelbuettel and Romain Francois
6+
// Copyright (C) 2026 Dirk Eddelbuettel, Romain Francois and Iñaki Ucar
67
//
78
// This file is part of Rcpp.
89
//
@@ -43,7 +44,7 @@ namespace sugar{
4344
STORAGE lhs_ = lhs[i] ;
4445
if( traits::is_na<RTYPE>(lhs_) ) return lhs_ ;
4546
STORAGE rhs_ = rhs[i] ;
46-
return traits::is_na<RTYPE>(rhs_) ? rhs_ : (lhs_ * rhs_) ;
47+
return traits::is_na<RTYPE>(rhs_) ? rhs_ : RCPP_SAFE_MUL(lhs_, rhs_) ;
4748
}
4849

4950
inline R_xlen_t size() const { return lhs.size() ; }
@@ -96,7 +97,7 @@ namespace sugar{
9697
inline STORAGE operator[]( R_xlen_t i ) const {
9798
STORAGE rhs_ = rhs[i] ;
9899
if( traits::is_na<RTYPE>(rhs_) ) return rhs_ ;
99-
return lhs[i] * rhs_ ;
100+
return RCPP_SAFE_MUL(lhs[i], rhs_);
100101
}
101102

102103
inline R_xlen_t size() const { return lhs.size() ; }
@@ -148,7 +149,7 @@ namespace sugar{
148149
inline STORAGE operator[]( R_xlen_t i ) const {
149150
STORAGE lhs_ = lhs[i] ;
150151
if( traits::is_na<RTYPE>(lhs_) ) return lhs_ ;
151-
return lhs_ * rhs[i] ;
152+
return RCPP_SAFE_MUL(lhs_, rhs[i]);
152153
}
153154

154155
inline R_xlen_t size() const { return lhs.size() ; }
@@ -197,7 +198,7 @@ namespace sugar{
197198
lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){}
198199

199200
inline STORAGE operator[]( R_xlen_t i ) const {
200-
return lhs[i] * rhs[i] ;
201+
return RCPP_SAFE_MUL(lhs[i], rhs[i]);
201202
}
202203

203204
inline R_xlen_t size() const { return lhs.size() ; }
@@ -247,7 +248,7 @@ namespace sugar{
247248
inline STORAGE operator[]( R_xlen_t i ) const {
248249
if( rhs_na ) return rhs ;
249250
STORAGE x = lhs[i] ;
250-
return Rcpp::traits::is_na<RTYPE>(x) ? x : (x * rhs) ;
251+
return Rcpp::traits::is_na<RTYPE>(x) ? x : RCPP_SAFE_MUL(x, rhs) ;
251252
}
252253

253254
inline R_xlen_t size() const { return lhs.size() ; }
@@ -293,7 +294,7 @@ namespace sugar{
293294
lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na<RTYPE>(rhs_) ) {}
294295

295296
inline STORAGE operator[]( R_xlen_t i ) const {
296-
return rhs_na ? rhs : (rhs * lhs[i] ) ;
297+
return rhs_na ? rhs : (rhs * lhs[i]);
297298
}
298299

299300
inline R_xlen_t size() const { return lhs.size() ; }
@@ -345,7 +346,7 @@ namespace sugar{
345346

346347
inline STORAGE operator[]( R_xlen_t i ) const {
347348
STORAGE x = lhs[i] ;
348-
return Rcpp::traits::is_na<RTYPE>(x) ? x : (x * rhs) ;
349+
return Rcpp::traits::is_na<RTYPE>(x) ? x : RCPP_SAFE_MUL(x, rhs);
349350
}
350351

351352
inline R_xlen_t size() const { return lhs.size() ; }
@@ -391,7 +392,7 @@ namespace sugar{
391392
lhs(lhs_.get_ref()), rhs(rhs_) {}
392393

393394
inline STORAGE operator[]( R_xlen_t i ) const {
394-
return rhs * lhs[i] ;
395+
return RCPP_SAFE_MUL(rhs, lhs[i]);
395396
}
396397

397398
inline R_xlen_t size() const { return lhs.size() ; }

inst/tinytest/cpp/sugar.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,15 @@ List runit_minus_seqlen(){
348348
) ;
349349
}
350350

351+
// [[Rcpp::export]]
352+
List runit_times_seqlen(){
353+
return List::create(
354+
seq_len(10) * 10,
355+
10 * seq_len(10),
356+
seq_len(10) * seq_len(10)
357+
) ;
358+
}
359+
351360
// [[Rcpp::export]]
352361
LogicalVector runit_plus_all( IntegerVector xx ){
353362
return all( (xx+xx) < 10 ) ;
@@ -467,6 +476,21 @@ List runit_times( IntegerVector xx ){
467476
) ;
468477
}
469478

479+
// [[Rcpp::export]]
480+
IntegerVector runit_times_ivv( IntegerVector x, IntegerVector y ){
481+
return x * y;
482+
}
483+
484+
// [[Rcpp::export]]
485+
IntegerVector runit_times_ivp( IntegerVector x, int y ){
486+
return x * y;
487+
}
488+
489+
// [[Rcpp::export]]
490+
IntegerVector runit_times_ipv( int x, IntegerVector y ){
491+
return x * y;
492+
}
493+
470494
// [[Rcpp::export]]
471495
List runit_divides( NumericVector xx ){
472496
return List::create(

inst/tinytest/test_sugar.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,12 +485,20 @@ expect_equal(fx( seq(-10, 10, length.out = 51), -25:25 ),
485485

486486

487487
# test.sugar.times <- function( ){
488+
expect_error(runit_times_ivv(.Machine$integer.max, 2), "overflow")
489+
expect_error(runit_times_ivp(.Machine$integer.max, 2), "overflow")
490+
expect_error(runit_times_ipv(.Machine$integer.max, 2), "overflow")
488491
fx <- runit_times
489492
expect_equal(fx(1:10) ,
490493
list(10L*(1:10), 10L*(1:10), (1:10)*(1:10), (1:10)*(1:10)*(1:10),
491494
c(NA,(2:10)*(2:10)), c(NA,10L*(2:10)), c(NA,10L*(2:10)), rep( NA_integer_, 10L )))
492495

493496

497+
# test.sugar.times.seqlen <- function( ){
498+
fx <- runit_times_seqlen
499+
expect_equal( fx() , list( seq(10, 100, 10), seq(10, 100, 10), 1:10*1:10) )
500+
501+
494502
# test.sugar.divides <- function( ){
495503
fx <- runit_divides
496504
expect_equal(fx(1:10) ,

0 commit comments

Comments
 (0)