From f8e15cc690ac58623d8c67ea028defcc6deac221 Mon Sep 17 00:00:00 2001 From: "Logan C. Brooks" Date: Tue, 16 Jul 2024 21:36:23 -0700 Subject: [PATCH] Combine x and ... in min, max, range Only call `vec_c` if dots are nonempty to stay fast in the empty case. --- R/type-vctr.R | 12 ++++++++++++ tests/testthat/test-type-vctr.R | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/R/type-vctr.R b/R/type-vctr.R index 9770bb9d4..5b3e059fa 100644 --- a/R/type-vctr.R +++ b/R/type-vctr.R @@ -545,6 +545,10 @@ vec_cast_or_na <- function(x, to, ...) { #' @export min.vctrs_vctr <- function(x, ..., na.rm = FALSE) { + if (dots_n(...) != 0L) { + x <- vec_c(x, ...) + } + if (vec_is_empty(x)) { return(vec_cast_or_na(Inf, x)) } @@ -566,6 +570,10 @@ min.vctrs_vctr <- function(x, ..., na.rm = FALSE) { #' @export max.vctrs_vctr <- function(x, ..., na.rm = FALSE) { + if (dots_n(...) != 0L) { + x <- vec_c(x, ...) + } + if (vec_is_empty(x)) { return(vec_cast_or_na(-Inf, x)) } @@ -587,6 +595,10 @@ max.vctrs_vctr <- function(x, ..., na.rm = FALSE) { #' @export range.vctrs_vctr <- function(x, ..., na.rm = FALSE) { + if (dots_n(...) != 0L) { + x <- vec_c(x, ...) + } + if (vec_is_empty(x)) { return(vec_cast_or_na(c(Inf, -Inf), x)) } diff --git a/tests/testthat/test-type-vctr.R b/tests/testthat/test-type-vctr.R index f47a8aa9e..a5bfede03 100644 --- a/tests/testthat/test-type-vctr.R +++ b/tests/testthat/test-type-vctr.R @@ -632,6 +632,18 @@ test_that("Summary generics behave identically to base for empty vctrs (#88)", { ) }) +test_that("methods combine `x` and `...` when generic expects them to (#1372)", { + x <- new_vctr(1) + y <- new_vctr(3) + + expect_identical(min(x, y), x) + expect_identical(min(y, x), x) + expect_identical(max(x, y), y) + expect_identical(max(y, x), y) + expect_identical(range(x, y), c(x, y)) + expect_identical(range(y, x), c(x, y)) +}) + test_that("generic predicates return logical vectors (#251)", { x <- new_vctr(c(1, 2)) expect_identical(is.finite(x), c(TRUE, TRUE))