diff --git a/inst/include/cpp11.hpp b/inst/include/cpp11.hpp index 550f23166..00b8d163b 100644 --- a/inst/include/cpp11.hpp +++ b/inst/include/cpp11.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include "cpp11/R.hpp" diff --git a/inst/include/cpp11/R.hpp b/inst/include/cpp11/R.hpp index 5579a8c94..982b42e63 100644 --- a/inst/include/cpp11/R.hpp +++ b/inst/include/cpp11/R.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #ifdef R_INTERNALS_H_ @@ -13,9 +13,11 @@ #ifndef R_NO_REMAP #define R_NO_REMAP #endif + #ifndef STRICT_R_HEADERS #define STRICT_R_HEADERS #endif + #include "R_ext/Boolean.h" #include "Rinternals.h" #include "Rversion.h" @@ -33,7 +35,6 @@ // clang-format on #include -#include "cpp11/altrep.hpp" #if defined(R_VERSION) && R_VERSION >= R_Version(4, 4, 0) // Use R's new macro diff --git a/inst/include/cpp11/altrep.hpp b/inst/include/cpp11/altrep.hpp index 12bc0916c..0d16e7be6 100644 --- a/inst/include/cpp11/altrep.hpp +++ b/inst/include/cpp11/altrep.hpp @@ -1,44 +1,8 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once -#include "Rversion.h" - -#if defined(R_VERSION) && R_VERSION >= R_Version(3, 5, 0) +// It would be nice to remove this since all supported versions of R have ALTREP, but +// some groups rely on both this `#define` and `altrep.hpp` itself existing, like arrow: +// https://github.com/r-lib/cpp11/issues/413 #define HAS_ALTREP -#endif - -#ifndef HAS_ALTREP - -#define ALTREP(x) false - -#define REAL_ELT(x, i) REAL(x)[i] -#define INTEGER_ELT(x, i) INTEGER(x)[i] -#define LOGICAL_ELT(x, i) LOGICAL(x)[i] -#define RAW_ELT(x, i) RAW(x)[i] - -#define SET_REAL_ELT(x, i, val) REAL(x)[i] = val -#define SET_INTEGER_ELT(x, i, val) INTEGER(x)[i] = val -#define SET_LOGICAL_ELT(x, i, val) LOGICAL(x)[i] = val -#define SET_RAW_ELT(x, i, val) RAW(x)[i] = val - -#define REAL_GET_REGION(...) \ - do { \ - } while (false) - -#define INTEGER_GET_REGION(...) \ - do { \ - } while (false) -#endif - -#if !defined HAS_ALTREP || (defined(R_VERSION) && R_VERSION < R_Version(3, 6, 0)) - -#define LOGICAL_GET_REGION(...) \ - do { \ - } while (false) - -#define RAW_GET_REGION(...) \ - do { \ - } while (false) - -#endif diff --git a/inst/include/cpp11/as.hpp b/inst/include/cpp11/as.hpp index 12ef05838..9152e5864 100644 --- a/inst/include/cpp11/as.hpp +++ b/inst/include/cpp11/as.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for modf diff --git a/inst/include/cpp11/attribute_proxy.hpp b/inst/include/cpp11/attribute_proxy.hpp index 31e029147..276ee8d33 100644 --- a/inst/include/cpp11/attribute_proxy.hpp +++ b/inst/include/cpp11/attribute_proxy.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for initializer_list diff --git a/inst/include/cpp11/data_frame.hpp b/inst/include/cpp11/data_frame.hpp index d5376e7d5..73143a2ca 100644 --- a/inst/include/cpp11/data_frame.hpp +++ b/inst/include/cpp11/data_frame.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for abs diff --git a/inst/include/cpp11/declarations.hpp b/inst/include/cpp11/declarations.hpp index d94afa39d..7aa879f19 100644 --- a/inst/include/cpp11/declarations.hpp +++ b/inst/include/cpp11/declarations.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include @@ -32,13 +32,10 @@ T& unmove(T&& t) { } } // namespace cpp11 -#ifdef HAS_UNWIND_PROTECT +// We would like to remove this, since all supported versions of R now support proper +// unwind protect, but some groups rely on it existing, like textshaping: +// https://github.com/r-lib/cpp11/issues/414 #define CPP11_UNWIND R_ContinueUnwind(err); -#else -#define CPP11_UNWIND \ - do { \ - } while (false); -#endif #define CPP11_ERROR_BUFSIZE 8192 @@ -60,7 +57,7 @@ T& unmove(T&& t) { if (buf[0] != '\0') { \ Rf_errorcall(R_NilValue, "%s", buf); \ } else if (err != R_NilValue) { \ - CPP11_UNWIND \ + R_ContinueUnwind(err); \ } \ return RET; #define END_CPP11 END_CPP11_EX(R_NilValue) diff --git a/inst/include/cpp11/doubles.hpp b/inst/include/cpp11/doubles.hpp index 8495f28fc..f8b2f64fa 100644 --- a/inst/include/cpp11/doubles.hpp +++ b/inst/include/cpp11/doubles.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for min, tranform @@ -50,7 +50,7 @@ inline void r_vector::get_region(SEXP x, R_xlen_t i, R_xlen_t n, typename r_vector::underlying_type* buf) { // NOPROTECT: likely too costly to unwind protect here REAL_GET_REGION(x, i, n, buf); -}; +} template <> inline bool r_vector::const_iterator::use_buf(bool is_altrep) { diff --git a/inst/include/cpp11/environment.hpp b/inst/include/cpp11/environment.hpp index b8e96d67b..23f54f9ce 100644 --- a/inst/include/cpp11/environment.hpp +++ b/inst/include/cpp11/environment.hpp @@ -1,23 +1,14 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for string, basic_string -#include "Rversion.h" // for R_VERSION, R_Version #include "cpp11/R.hpp" // for SEXP, SEXPREC, Rf_install, r_env_get... #include "cpp11/as.hpp" // for as_sexp #include "cpp11/protect.hpp" // for protect, protect::function, safe, unwin... #include "cpp11/sexp.hpp" // for sexp -#if R_VERSION >= R_Version(4, 0, 0) -#define HAS_REMOVE_VAR_FROM_FRAME -#endif - -#ifndef HAS_REMOVE_VAR_FROM_FRAME -#include "cpp11/function.hpp" -#endif - namespace cpp11 { class environment { @@ -53,12 +44,7 @@ class environment { void remove(SEXP name) { PROTECT(name); -#ifdef HAS_REMOVE_VAR_FROM_FRAME R_removeVarFromFrame(name, env_); -#else - auto remove = package("base")["remove"]; - remove(name, "envir"_nm = env_); -#endif UNPROTECT(1); } diff --git a/inst/include/cpp11/external_pointer.hpp b/inst/include/cpp11/external_pointer.hpp index 070433a33..e441bc0f8 100644 --- a/inst/include/cpp11/external_pointer.hpp +++ b/inst/include/cpp11/external_pointer.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for nullptr_t, NULL @@ -57,7 +57,8 @@ class external_pointer { external_pointer(SEXP data) : data_(valid_type(data)) {} - external_pointer(pointer p, bool use_deleter = true, bool finalize_on_exit = true, SEXP prot = R_NilValue) + external_pointer(pointer p, bool use_deleter = true, bool finalize_on_exit = true, + SEXP prot = R_NilValue) : data_(safe[R_MakeExternalPtr]((void*)p, R_NilValue, prot)) { if (use_deleter) { R_RegisterCFinalizerEx(data_, r_deleter, static_cast(finalize_on_exit)); diff --git a/inst/include/cpp11/function.hpp b/inst/include/cpp11/function.hpp index c719a9639..23a646cba 100644 --- a/inst/include/cpp11/function.hpp +++ b/inst/include/cpp11/function.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for strcmp diff --git a/inst/include/cpp11/integers.hpp b/inst/include/cpp11/integers.hpp index 53145e795..ca4261be6 100644 --- a/inst/include/cpp11/integers.hpp +++ b/inst/include/cpp11/integers.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for min @@ -51,7 +51,7 @@ inline void r_vector::get_region(SEXP x, R_xlen_t i, R_xlen_t n, typename r_vector::underlying_type* buf) { // NOPROTECT: likely too costly to unwind protect here INTEGER_GET_REGION(x, i, n, buf); -}; +} template <> inline bool r_vector::const_iterator::use_buf(bool is_altrep) { diff --git a/inst/include/cpp11/list.hpp b/inst/include/cpp11/list.hpp index 91cae6f33..9df36cf7e 100644 --- a/inst/include/cpp11/list.hpp +++ b/inst/include/cpp11/list.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for initializer_list @@ -54,7 +54,7 @@ template <> inline void r_vector::get_region(SEXP x, R_xlen_t i, R_xlen_t n, typename r_vector::underlying_type* buf) { cpp11::stop("Unreachable!"); -}; +} template <> inline bool r_vector::const_iterator::use_buf(bool is_altrep) { diff --git a/inst/include/cpp11/list_of.hpp b/inst/include/cpp11/list_of.hpp index 8ba15800a..979a338df 100644 --- a/inst/include/cpp11/list_of.hpp +++ b/inst/include/cpp11/list_of.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for string, basic_string diff --git a/inst/include/cpp11/logicals.hpp b/inst/include/cpp11/logicals.hpp index 25806d253..e834482b5 100644 --- a/inst/include/cpp11/logicals.hpp +++ b/inst/include/cpp11/logicals.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for min @@ -50,7 +50,7 @@ inline void r_vector::get_region(SEXP x, R_xlen_t i, R_xlen_t n, typename r_vector::underlying_type* buf) { // NOPROTECT: likely too costly to unwind protect here LOGICAL_GET_REGION(x, i, n, buf); -}; +} template <> inline bool r_vector::const_iterator::use_buf(bool is_altrep) { diff --git a/inst/include/cpp11/matrix.hpp b/inst/include/cpp11/matrix.hpp index d69c26ebc..0d53143ef 100644 --- a/inst/include/cpp11/matrix.hpp +++ b/inst/include/cpp11/matrix.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include diff --git a/inst/include/cpp11/named_arg.hpp b/inst/include/cpp11/named_arg.hpp index c033d54aa..2614e6959 100644 --- a/inst/include/cpp11/named_arg.hpp +++ b/inst/include/cpp11/named_arg.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for size_t diff --git a/inst/include/cpp11/protect.hpp b/inst/include/cpp11/protect.hpp index 2d6093b0c..b30d95c45 100644 --- a/inst/include/cpp11/protect.hpp +++ b/inst/include/cpp11/protect.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for longjmp, setjmp, jmp_buf @@ -15,11 +15,11 @@ #include "R_ext/Error.h" // for Rf_error, Rf_warning #include "R_ext/Print.h" // for REprintf #include "R_ext/Utils.h" // for R_CheckUserInterrupt -#include "Rversion.h" // for R_VERSION, R_Version -#if defined(R_VERSION) && R_VERSION >= R_Version(3, 5, 0) +// We would like to remove this, since all supported versions of R now support proper +// unwind protect, but some groups rely on it existing, like arrow and systemfonts +// https://github.com/r-lib/cpp11/issues/412 #define HAS_UNWIND_PROTECT -#endif #ifdef CPP11_USE_FMT #define FMT_HEADER_ONLY @@ -33,8 +33,6 @@ class unwind_exception : public std::exception { unwind_exception(SEXP token_) : token(token_) {} }; -#ifdef HAS_UNWIND_PROTECT - /// Unwind Protection from C longjmp's, like those used in R error handling /// /// @param code The code to which needs to be protected, as a nullary callable @@ -97,15 +95,6 @@ unwind_protect(Fun&& code) { return out; } -#else -// Don't do anything if we don't have unwind protect. This will leak C++ resources, -// including those held by cpp11 objects, but the other alternatives are also not great. -template -decltype(std::declval()()) unwind_protect(Fun&& code) { - return std::forward(code)(); -} -#endif - namespace detail { template diff --git a/inst/include/cpp11/r_bool.hpp b/inst/include/cpp11/r_bool.hpp index eb2b1eda7..a66e77dc1 100644 --- a/inst/include/cpp11/r_bool.hpp +++ b/inst/include/cpp11/r_bool.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for numeric_limits diff --git a/inst/include/cpp11/r_string.hpp b/inst/include/cpp11/r_string.hpp index 63dbafb9f..25022aa7b 100644 --- a/inst/include/cpp11/r_string.hpp +++ b/inst/include/cpp11/r_string.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for string, basic_string, operator== diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 637981d33..a9848596b 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for ptrdiff_t, size_t @@ -422,7 +422,7 @@ inline r_vector& r_vector::operator=(const r_vector& rhs) { length_ = rhs.length_; return *this; -}; +} // Same reasoning as `r_vector(r_vector&& x)` constructor template @@ -448,7 +448,7 @@ inline r_vector& r_vector::operator=(r_vector&& rhs) { rhs.length_ = 0; return *this; -}; +} template inline r_vector::operator SEXP() const { @@ -1325,7 +1325,8 @@ inline SEXP r_vector::reserve_data(SEXP x, bool is_altrep, R_xlen_t size) { SEXP out = PROTECT(resize_data(x, is_altrep, size)); // Resize names, if required - SEXP names = Rf_getAttrib(x, R_NamesSymbol); + // Protection seems needed to make rchk happy + SEXP names = PROTECT(Rf_getAttrib(x, R_NamesSymbol)); if (names != R_NilValue) { if (Rf_xlength(names) != size) { names = resize_names(names, size); @@ -1340,7 +1341,7 @@ inline SEXP r_vector::reserve_data(SEXP x, bool is_altrep, R_xlen_t size) { // Does not look like it would ever error in our use cases, so no `safe[]`. Rf_copyMostAttrib(x, out); - UNPROTECT(1); + UNPROTECT(2); return out; } diff --git a/inst/include/cpp11/raws.hpp b/inst/include/cpp11/raws.hpp index ba152a5ba..218b4bb90 100644 --- a/inst/include/cpp11/raws.hpp +++ b/inst/include/cpp11/raws.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for min @@ -58,7 +58,7 @@ inline void r_vector::get_region(SEXP x, R_xlen_t i, R_xlen_t n, typename r_vector::underlying_type* buf) { // NOPROTECT: likely too costly to unwind protect here RAW_GET_REGION(x, i, n, buf); -}; +} template <> inline bool r_vector::const_iterator::use_buf(bool is_altrep) { diff --git a/inst/include/cpp11/sexp.hpp b/inst/include/cpp11/sexp.hpp index b8d24dac1..aceeff3fc 100644 --- a/inst/include/cpp11/sexp.hpp +++ b/inst/include/cpp11/sexp.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for size_t diff --git a/inst/include/cpp11/strings.hpp b/inst/include/cpp11/strings.hpp index a39859783..c72d25b8f 100644 --- a/inst/include/cpp11/strings.hpp +++ b/inst/include/cpp11/strings.hpp @@ -1,5 +1,5 @@ -// cpp11 version: 0.5.0 -// vendored on: 2024-09-24 +// cpp11 version: 0.5.1 +// vendored on: 2024-12-07 #pragma once #include // for initializer_list @@ -51,7 +51,7 @@ template <> inline void r_vector::get_region(SEXP x, R_xlen_t i, R_xlen_t n, typename r_vector::underlying_type* buf) { cpp11::stop("Unreachable!"); -}; +} template <> inline bool r_vector::const_iterator::use_buf(bool is_altrep) {