diff --git a/cpp11test/src/test-as.cpp b/cpp11test/src/test-as.cpp index 9c65a689..b4e5d9cc 100644 --- a/cpp11test/src/test-as.cpp +++ b/cpp11test/src/test-as.cpp @@ -90,6 +90,19 @@ context("as_cpp-C++") { UNPROTECT(1); } + test_that("as_cpp(INTSEXP)") { + enum class Response: char { YES, NO, MAYBE }; + SEXP r = PROTECT(Rf_allocVector(INTSXP, 1)); + + for (Response e : {Response::YES, Response::NO, Response::MAYBE, static_cast(42)}) { + INTEGER(r)[0] = static_cast(e); + auto x = cpp11::as_cpp(r); + expect_true(x == e); + } + + UNPROTECT(1); + } + test_that("as_cpp(REALSXP)") { SEXP r = PROTECT(Rf_allocVector(REALSXP, 1)); REAL(r)[0] = 1.2; diff --git a/inst/include/cpp11/as.hpp b/inst/include/cpp11/as.hpp index bcadfc57..3523f240 100644 --- a/inst/include/cpp11/as.hpp +++ b/inst/include/cpp11/as.hpp @@ -96,7 +96,13 @@ enable_if_integral as_cpp(SEXP from) { template enable_if_enum as_cpp(SEXP from) { if (Rf_isInteger(from)) { - return static_cast(as_cpp::type>(from)); + using underlying_type = typename std::underlying_type::type; + using int_type = typename std::conditional< + std::is_same::value, + int, // as_cpp would trigger undesired string conversions + underlying_type + >::type; + return static_cast(as_cpp(from)); } stop("Expected single integer value");