| 381 | static SEXP Max(SEXP alt, Rboolean narm) { return MinMax<false>(alt, narm); } |
| 382 | |
| 383 | static SEXP Sum(SEXP alt, Rboolean narm) { |
| 384 | if (IsMaterialized(alt)) { |
| 385 | return nullptr; |
| 386 | } |
| 387 | |
| 388 | using data_type = typename std::conditional<sexp_type == REALSXP, double, int>::type; |
| 389 | |
| 390 | const auto& chunked_array = GetChunkedArray(alt); |
| 391 | bool na_rm = narm == TRUE; |
| 392 | auto null_count = chunked_array->null_count(); |
| 393 | |
| 394 | if (!na_rm && null_count > 0) { |
| 395 | return cpp11::as_sexp(cpp11::na<data_type>()); |
| 396 | } |
| 397 | auto options = NaRmOptions(na_rm); |
| 398 | |
| 399 | const auto& sum = |
| 400 | ValueOrStop(arrow::compute::CallFunction("sum", {chunked_array}, options.get())); |
| 401 | |
| 402 | if (sexp_type == INTSXP) { |
| 403 | // When calling the "sum" function on an int32 array, we get an Int64 scalar |
| 404 | // in case of overflow, make it a double like R |
| 405 | int64_t value = internal::checked_cast<const Int64Scalar&>(*sum.scalar()).value; |
| 406 | if (value <= INT32_MIN || value > INT32_MAX) { |
| 407 | return Rf_ScalarReal(static_cast<double>(value)); |
| 408 | } else { |
| 409 | return Rf_ScalarInteger(static_cast<int>(value)); |
| 410 | } |
| 411 | } else { |
| 412 | return Rf_ScalarReal( |
| 413 | internal::checked_cast<const DoubleScalar&>(*sum.scalar()).value); |
| 414 | } |
| 415 | } |
| 416 | }; |
| 417 | template <int sexp_type> |
| 418 | R_altrep_class_t AltrepVectorPrimitive<sexp_type>::class_t; |
nothing calls this directly
no test coverage detected