From 7a72ec90a106ddf72a6a49e253354c7fe77e345f Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 03:31:51 -0400 Subject: [PATCH 01/14] implement fix for #445 --- inst/include/cpp11/list.hpp | 5 ++++- inst/include/cpp11/r_vector.hpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/inst/include/cpp11/list.hpp b/inst/include/cpp11/list.hpp index be29bb2a..66cd99c7 100644 --- a/inst/include/cpp11/list.hpp +++ b/inst/include/cpp11/list.hpp @@ -79,7 +79,8 @@ inline r_vector::r_vector(std::initializer_list il) : cpp11::r_vector(safe[Rf_allocVector](VECSXP, il.size())), capacity_(il.size()) { unwind_protect([&] { - SEXP names = Rf_allocVector(STRSXP, capacity_); + SEXP names; + PROTECT(names = Rf_allocVector(STRSXP, capacity_)); Rf_setAttrib(data_, R_NamesSymbol, names); auto it = il.begin(); @@ -91,6 +92,8 @@ inline r_vector::r_vector(std::initializer_list il) SEXP name = Rf_mkCharCE(it->name(), CE_UTF8); SET_STRING_ELT(names, i, name); } + + UNPROTECT(1); }); } diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 576f4fe6..b2e512fe 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -865,7 +865,8 @@ inline r_vector::r_vector(std::initializer_list il) } unwind_protect([&] { - SEXP names = Rf_allocVector(STRSXP, capacity_); + SEXP names; + PROTECT(names = Rf_allocVector(STRSXP, capacity_)); Rf_setAttrib(data_, R_NamesSymbol, names); auto it = il.begin(); @@ -890,6 +891,8 @@ inline r_vector::r_vector(std::initializer_list il) SEXP name = Rf_mkCharCE(it->name(), CE_UTF8); SET_STRING_ELT(names, i, name); } + + UNPROTECT(1); }); } From fcb7756fe016d953aa5b410aba57678c17ad1615 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 10:32:24 -0400 Subject: [PATCH 02/14] only one cstdlib in data_frame.hpp --- inst/include/cpp11/data_frame.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/inst/include/cpp11/data_frame.hpp b/inst/include/cpp11/data_frame.hpp index a4748de0..6be16400 100644 --- a/inst/include/cpp11/data_frame.hpp +++ b/inst/include/cpp11/data_frame.hpp @@ -1,7 +1,6 @@ #pragma once -#include // for abs -#include +#include // for abs #include // for initializer_list #include // for string, basic_string #include // for move From 012e4e0bd589722fbad43e0cf522bf08166d5251 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 10:33:24 -0400 Subject: [PATCH 03/14] use inline constexpr for doubles/integers/list/logicals/strings --- inst/include/cpp11/doubles.hpp | 2 +- inst/include/cpp11/integers.hpp | 2 +- inst/include/cpp11/list.hpp | 2 +- inst/include/cpp11/logicals.hpp | 2 +- inst/include/cpp11/strings.hpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/inst/include/cpp11/doubles.hpp b/inst/include/cpp11/doubles.hpp index dcab086d..aa5c6044 100644 --- a/inst/include/cpp11/doubles.hpp +++ b/inst/include/cpp11/doubles.hpp @@ -16,7 +16,7 @@ namespace cpp11 { template <> -inline SEXPTYPE r_vector::get_sexptype() { +inline constexpr SEXPTYPE r_vector::get_sexptype() { return REALSXP; } diff --git a/inst/include/cpp11/integers.hpp b/inst/include/cpp11/integers.hpp index 68fd8e4d..dbf8471e 100644 --- a/inst/include/cpp11/integers.hpp +++ b/inst/include/cpp11/integers.hpp @@ -17,7 +17,7 @@ namespace cpp11 { template <> -inline SEXPTYPE r_vector::get_sexptype() { +inline constexpr SEXPTYPE r_vector::get_sexptype() { return INTSXP; } diff --git a/inst/include/cpp11/list.hpp b/inst/include/cpp11/list.hpp index 66cd99c7..e83614f3 100644 --- a/inst/include/cpp11/list.hpp +++ b/inst/include/cpp11/list.hpp @@ -14,7 +14,7 @@ namespace cpp11 { template <> -inline SEXPTYPE r_vector::get_sexptype() { +inline constexpr SEXPTYPE r_vector::get_sexptype() { return VECSXP; } diff --git a/inst/include/cpp11/logicals.hpp b/inst/include/cpp11/logicals.hpp index 45d3d1cc..02bb712c 100644 --- a/inst/include/cpp11/logicals.hpp +++ b/inst/include/cpp11/logicals.hpp @@ -16,7 +16,7 @@ namespace cpp11 { template <> -inline SEXPTYPE r_vector::get_sexptype() { +inline constexpr SEXPTYPE r_vector::get_sexptype() { return LGLSXP; } diff --git a/inst/include/cpp11/strings.hpp b/inst/include/cpp11/strings.hpp index 393f2a8c..aa559be0 100644 --- a/inst/include/cpp11/strings.hpp +++ b/inst/include/cpp11/strings.hpp @@ -17,7 +17,7 @@ namespace cpp11 { template <> -inline SEXPTYPE r_vector::get_sexptype() { +inline constexpr SEXPTYPE r_vector::get_sexptype() { return STRSXP; } From 2be654254c63b7689a0464156e976631df004946 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 10:33:42 -0400 Subject: [PATCH 04/14] use noexcept in protect/sexp --- inst/include/cpp11/protect.hpp | 3 ++- inst/include/cpp11/sexp.hpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/inst/include/cpp11/protect.hpp b/inst/include/cpp11/protect.hpp index 9cb4876a..dac0dec5 100644 --- a/inst/include/cpp11/protect.hpp +++ b/inst/include/cpp11/protect.hpp @@ -186,7 +186,8 @@ struct protect { }; constexpr struct protect safe = {}; -inline void check_user_interrupt() { safe[R_CheckUserInterrupt](); } +// @pachadotdev: + noexcept +inline void check_user_interrupt() noexcept { safe[R_CheckUserInterrupt](); } #ifdef CPP11_USE_FMT template diff --git a/inst/include/cpp11/sexp.hpp b/inst/include/cpp11/sexp.hpp index 74205e69..a4a757f3 100644 --- a/inst/include/cpp11/sexp.hpp +++ b/inst/include/cpp11/sexp.hpp @@ -64,8 +64,9 @@ class sexp { return attribute_proxy(*this, R_NamesSymbol); } - operator SEXP() const { return data_; } - SEXP data() const { return data_; } + // @pachadotdev: + noexcept + operator SEXP() const noexcept { return data_; } + SEXP data() const noexcept { return data_; } /// DEPRECATED: Do not use this, it will be removed soon. operator double() const { return REAL_ELT(data_, 0); } From 91c3bd4e6aa4bfa392aefa4992bd34f4817b5e80 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 17:35:20 -0400 Subject: [PATCH 05/14] noexcept in operator SEXP (attribute proxy) --- inst/include/cpp11/attribute_proxy.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/include/cpp11/attribute_proxy.hpp b/inst/include/cpp11/attribute_proxy.hpp index 64e7436b..4b7b4002 100644 --- a/inst/include/cpp11/attribute_proxy.hpp +++ b/inst/include/cpp11/attribute_proxy.hpp @@ -42,7 +42,7 @@ class attribute_proxy { return *this; } - operator SEXP() const { return safe[Rf_getAttrib](parent_.data(), symbol_); } + operator SEXP() const noexcept { return safe[Rf_getAttrib](parent_.data(), symbol_); } }; } // namespace cpp11 From 472f40f96bd014c6008fc5dd32791f797a19555b Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 17:55:17 -0400 Subject: [PATCH 06/14] + noexcept --- inst/include/cpp11/data_frame.hpp | 16 +++++---- inst/include/cpp11/environment.hpp | 5 +-- inst/include/cpp11/external_pointer.hpp | 8 +++-- inst/include/cpp11/function.hpp | 2 +- inst/include/cpp11/matrix.hpp | 5 +-- inst/include/cpp11/named_arg.hpp | 8 +++-- inst/include/cpp11/r_bool.hpp | 3 +- inst/include/cpp11/r_vector.hpp | 44 +++++++++++++++---------- inst/include/cpp11/raws.hpp | 3 +- inst/include/cpp11/sexp.hpp | 7 ++-- inst/include/cpp11/strings.hpp | 20 +++++++---- 11 files changed, 77 insertions(+), 44 deletions(-) diff --git a/inst/include/cpp11/data_frame.hpp b/inst/include/cpp11/data_frame.hpp index 6be16400..41d47150 100644 --- a/inst/include/cpp11/data_frame.hpp +++ b/inst/include/cpp11/data_frame.hpp @@ -35,7 +35,8 @@ class data_frame : public list { return R_NilValue; } - static R_xlen_t calc_nrow(SEXP x) { + // @pachadotdev: + noexcept + static R_xlen_t calc_nrow(SEXP x) noexcept { auto nms = get_attrib0(x, R_RowNamesSymbol); bool has_short_rownames = (Rf_isInteger(nms) && Rf_xlength(nms) == 2 && INTEGER(nms)[0] == NA_INTEGER); @@ -58,8 +59,8 @@ class data_frame : public list { /* Adapted from * https://github.com/wch/r-source/blob/f2a0dfab3e26fb42b8b296fcba40cbdbdbec767d/src/main/attrib.c#L198-L207 */ - R_xlen_t nrow() const { return calc_nrow(*this); } - R_xlen_t ncol() const { return size(); } + R_xlen_t nrow() const noexcept { return calc_nrow(*this); } + R_xlen_t ncol() const noexcept { return size(); } }; namespace writable { @@ -89,13 +90,16 @@ class data_frame : public cpp11::data_frame { using cpp11::data_frame::ncol; using cpp11::data_frame::nrow; - attribute_proxy attr(const char* name) const { return {*this, name}; } + // @pachadotdev: + noexcept + attribute_proxy attr(const char* name) const noexcept const { + return {*this, name}; + } - attribute_proxy attr(const std::string& name) const { + attribute_proxy attr(const std::string& name) const noexcept { return {*this, name.c_str()}; } - attribute_proxy attr(SEXP name) const { return {*this, name}; } + attribute_proxy attr(SEXP name) const noexcept { return {*this, name}; } attribute_proxy names() const { return {*this, R_NamesSymbol}; } }; diff --git a/inst/include/cpp11/environment.hpp b/inst/include/cpp11/environment.hpp index eeee9236..2d9ba0c3 100644 --- a/inst/include/cpp11/environment.hpp +++ b/inst/include/cpp11/environment.hpp @@ -48,9 +48,10 @@ class environment { void remove(const char* name) { remove(safe[Rf_install](name)); } - R_xlen_t size() const { return Rf_xlength(env_); } + // @pachadotdev: + noexcept + R_xlen_t size() const noexcept { return Rf_xlength(env_); } - operator SEXP() const { return env_; } + operator SEXP() const noexcept { return env_; } }; } // namespace cpp11 diff --git a/inst/include/cpp11/external_pointer.hpp b/inst/include/cpp11/external_pointer.hpp index a62134ec..6988c4d6 100644 --- a/inst/include/cpp11/external_pointer.hpp +++ b/inst/include/cpp11/external_pointer.hpp @@ -12,8 +12,9 @@ namespace cpp11 { +// @pachadotdev: + noexcept template -void default_deleter(T* obj) { +void default_deleter(T* obj) noexcept{ delete obj; } @@ -33,12 +34,13 @@ class external_pointer { return data; } - static void r_deleter(SEXP p) { + // @pachadotdev: + noexcept + static void r_deleter(SEXP p) noexcept { if (detail::r_typeof(p) != EXTPTRSXP) return; T* ptr = static_cast(R_ExternalPtrAddr(p)); - if (ptr == NULL) { + if (ptr == nullptr) { return; } diff --git a/inst/include/cpp11/function.hpp b/inst/include/cpp11/function.hpp index 42fbdcf6..448a6b27 100644 --- a/inst/include/cpp11/function.hpp +++ b/inst/include/cpp11/function.hpp @@ -1,6 +1,6 @@ #pragma once -#include // for strcmp +#include // for std::strcmp (@pachadotdev use std qualifiers) #include // for snprintf #include // for string, basic_string diff --git a/inst/include/cpp11/matrix.hpp b/inst/include/cpp11/matrix.hpp index 8345068f..f7990300 100644 --- a/inst/include/cpp11/matrix.hpp +++ b/inst/include/cpp11/matrix.hpp @@ -184,9 +184,10 @@ class matrix : public matrix_slices { SEXP data() const { return vector_.data(); } - R_xlen_t size() const { return vector_.size(); } + // @pachadotdev: + noexcept + R_xlen_t size() const noexcept { return vector_.size(); } - operator SEXP() const { return SEXP(vector_); } + operator SEXP() const noexcept { return SEXP(vector_); } // operator sexp() { return sexp(vector_); } diff --git a/inst/include/cpp11/named_arg.hpp b/inst/include/cpp11/named_arg.hpp index df7ba935..07183bc8 100644 --- a/inst/include/cpp11/named_arg.hpp +++ b/inst/include/cpp11/named_arg.hpp @@ -11,7 +11,8 @@ namespace cpp11 { class named_arg { public: - explicit named_arg(const char* name) : name_(name), value_(R_NilValue) {} + // @pachadotdev: + noexcept + explicit named_arg(const char* name) noexcept : name_(name), value_(R_NilValue) {} named_arg& operator=(std::initializer_list il) { value_ = as_sexp(il); return *this; @@ -39,7 +40,10 @@ class named_arg { namespace literals { -inline named_arg operator""_nm(const char* name, std::size_t) { return named_arg(name); } +// @pachadotdev: + noexcept +inline named_arg operator""_nm(const char* name, std::size_t) noexcept { + return named_arg(name); +} } // namespace literals diff --git a/inst/include/cpp11/r_bool.hpp b/inst/include/cpp11/r_bool.hpp index 4ea36da8..f11b111d 100644 --- a/inst/include/cpp11/r_bool.hpp +++ b/inst/include/cpp11/r_bool.hpp @@ -66,8 +66,9 @@ enable_if_r_bool as_sexp(T from) { return res; } +// @pachadotdev: + noexcept template <> -inline r_bool na() { +inline r_bool na() noexcept { return NA_LOGICAL; } diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index b2e512fe..f1c0691d 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -65,8 +65,9 @@ class r_vector { r_vector& operator=(const r_vector& rhs); r_vector& operator=(r_vector&& rhs); - operator SEXP() const; - operator sexp() const; + // @pachadotdev: + noexcept + operator SEXP() noexcept const; + operator sexp() noexcept const; #ifdef LONG_VECTOR_SUPPORT T operator[](const int pos) const; @@ -85,9 +86,10 @@ class r_vector { bool contains(const r_string& name) const; bool is_altrep() const; bool named() const; - R_xlen_t size() const; - bool empty() const; - SEXP data() const; + // @pachadotdev: + noexcept + R_xlen_t size() noexcept const; + bool empty() no except const; + SEXP data() noexcept const; const sexp attr(const char* name) const; const sexp attr(const std::string& name) const; @@ -95,10 +97,11 @@ class r_vector { r_vector names() const; - const_iterator begin() const; - const_iterator end() const; - const_iterator cbegin() const; - const_iterator cend() const; + // @pachadotdev: + noexcept + const_iterator begin() noexcept const; + const_iterator end() noexcept const; + const_iterator cbegin() noexcept const; + const_iterator cend() noexcept const; const_iterator find(const r_string& name) const; class const_iterator { @@ -448,13 +451,15 @@ inline r_vector& r_vector::operator=(r_vector&& rhs) { return *this; } +// @pachadotdev: + noexcept template -inline r_vector::operator SEXP() const { +inline r_vector::operator SEXP() const noexcept { return data_; } +// @pachadotdev: + noexcept template -inline r_vector::operator sexp() const { +inline r_vector::operator sexp() const noexcept { return data_; } @@ -636,23 +641,27 @@ inline SEXP r_vector::valid_length(SEXP x, R_xlen_t n) { throw std::length_error(message); } +// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::begin() const { +inline typename r_vector::const_iterator r_vector::begin() const noexcept { return const_iterator(this, 0); } +// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::end() const { +inline typename r_vector::const_iterator r_vector::end() const noexcept{ return const_iterator(this, length_); } +// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::cbegin() const { +inline typename r_vector::const_iterator r_vector::cbegin() const noexcept { return const_iterator(this, 0); } +// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::cend() const { +inline typename r_vector::const_iterator r_vector::cend() const noexcept { return const_iterator(this, length_); } @@ -1070,8 +1079,9 @@ inline void r_vector::push_back(T value) { ++length_; } +// @pachadotdev: + noexcept template -inline void r_vector::pop_back() { +inline void r_vector::pop_back() noexcept { --length_; } @@ -1128,7 +1138,7 @@ inline typename r_vector::iterator r_vector::erase(R_xlen_t pos) { } template -inline void r_vector::clear() { +inline void r_vector::clear() noexcept { length_ = 0; } diff --git a/inst/include/cpp11/raws.hpp b/inst/include/cpp11/raws.hpp index f16a6e39..d59d2856 100644 --- a/inst/include/cpp11/raws.hpp +++ b/inst/include/cpp11/raws.hpp @@ -67,9 +67,10 @@ typedef r_vector raws; namespace writable { +// @pachadotdev: + noexcept template <> inline void r_vector::set_elt(SEXP x, R_xlen_t i, - typename r_vector::underlying_type value) { + typename r_vector::underlying_type value) noexcept { // NOPROTECT: Likely too costly to unwind protect every set elt #if R_VERSION >= R_Version(4, 2, 0) SET_RAW_ELT(x, i, value); diff --git a/inst/include/cpp11/sexp.hpp b/inst/include/cpp11/sexp.hpp index a4a757f3..2f1344e1 100644 --- a/inst/include/cpp11/sexp.hpp +++ b/inst/include/cpp11/sexp.hpp @@ -68,12 +68,13 @@ class sexp { operator SEXP() const noexcept { return data_; } SEXP data() const noexcept { return data_; } + // @pachadotdev: + noexcept /// DEPRECATED: Do not use this, it will be removed soon. - operator double() const { return REAL_ELT(data_, 0); } + operator double() const noexcept { return REAL_ELT(data_, 0); } /// DEPRECATED: Do not use this, it will be removed soon. - operator size_t() const { return REAL_ELT(data_, 0); } + operator size_t() const noexcept { returnv REAL_ELT(data_, 0); } /// DEPRECATED: Do not use this, it will be removed soon. - operator bool() const { return LOGICAL_ELT(data_, 0); } + operator bool() const noexcept { return LOGICAL_ELT(data_, 0); } }; } // namespace cpp11 diff --git a/inst/include/cpp11/strings.hpp b/inst/include/cpp11/strings.hpp index aa559be0..22253066 100644 --- a/inst/include/cpp11/strings.hpp +++ b/inst/include/cpp11/strings.hpp @@ -132,17 +132,25 @@ inline r_vector::r_vector(std::initializer_list il) typedef r_vector strings; +// @pachadotdev: +// 1st name - reserve one slot, then emplace +// 2nd, 3rd, ..., Nth name: reserve exactly one more, then emplace template inline void r_vector::push_back(const named_arg& value) { push_back(value.value()); - if (Rf_xlength(names()) == 0) { - cpp11::writable::strings new_nms(size()); - names() = new_nms; - } + cpp11::writable::strings nms(names()); - nms[size() - 1] = value.name(); -} + if (nms.size() == 0) { + nms.reserve(1); + nms.emplace_back(value.name()); + } else { + nms.reserve(nms.size() + 1); + nms.emplace_back(value.name()); + } + + names() = nms; +} } // namespace writable } // namespace cpp11 From 4209cf084e2bb395c1149a7808abe6a3f1d64be2 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 17:55:37 -0400 Subject: [PATCH 07/14] clang format --- inst/include/cpp11/external_pointer.hpp | 2 +- inst/include/cpp11/r_vector.hpp | 2 +- inst/include/cpp11/raws.hpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/inst/include/cpp11/external_pointer.hpp b/inst/include/cpp11/external_pointer.hpp index 6988c4d6..6b63864a 100644 --- a/inst/include/cpp11/external_pointer.hpp +++ b/inst/include/cpp11/external_pointer.hpp @@ -14,7 +14,7 @@ namespace cpp11 { // @pachadotdev: + noexcept template -void default_deleter(T* obj) noexcept{ +void default_deleter(T* obj) noexcept { delete obj; } diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index f1c0691d..8c854116 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -649,7 +649,7 @@ inline typename r_vector::const_iterator r_vector::begin() const noexcept // @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::end() const noexcept{ +inline typename r_vector::const_iterator r_vector::end() const noexcept { return const_iterator(this, length_); } diff --git a/inst/include/cpp11/raws.hpp b/inst/include/cpp11/raws.hpp index d59d2856..9ee2dbc0 100644 --- a/inst/include/cpp11/raws.hpp +++ b/inst/include/cpp11/raws.hpp @@ -69,8 +69,8 @@ namespace writable { // @pachadotdev: + noexcept template <> -inline void r_vector::set_elt(SEXP x, R_xlen_t i, - typename r_vector::underlying_type value) noexcept { +inline void r_vector::set_elt( + SEXP x, R_xlen_t i, typename r_vector::underlying_type value) noexcept { // NOPROTECT: Likely too costly to unwind protect every set elt #if R_VERSION >= R_Version(4, 2, 0) SET_RAW_ELT(x, i, value); From b0b3f472b28b2ed454558a6c2dced8c67f0f8c77 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 19:11:38 -0400 Subject: [PATCH 08/14] rollback noexcept --- inst/include/cpp11/attribute_proxy.hpp | 2 +- inst/include/cpp11/data_frame.hpp | 14 ++++----- inst/include/cpp11/doubles.hpp | 2 +- inst/include/cpp11/environment.hpp | 5 ++- inst/include/cpp11/external_pointer.hpp | 6 ++-- inst/include/cpp11/integers.hpp | 2 +- inst/include/cpp11/list.hpp | 2 +- inst/include/cpp11/logicals.hpp | 2 +- inst/include/cpp11/matrix.hpp | 5 ++- inst/include/cpp11/named_arg.hpp | 6 ++-- inst/include/cpp11/protect.hpp | 3 +- inst/include/cpp11/r_vector.hpp | 42 ++++++++++--------------- inst/include/cpp11/raws.hpp | 3 +- inst/include/cpp11/sexp.hpp | 12 +++---- 14 files changed, 42 insertions(+), 64 deletions(-) diff --git a/inst/include/cpp11/attribute_proxy.hpp b/inst/include/cpp11/attribute_proxy.hpp index 4b7b4002..64e7436b 100644 --- a/inst/include/cpp11/attribute_proxy.hpp +++ b/inst/include/cpp11/attribute_proxy.hpp @@ -42,7 +42,7 @@ class attribute_proxy { return *this; } - operator SEXP() const noexcept { return safe[Rf_getAttrib](parent_.data(), symbol_); } + operator SEXP() const { return safe[Rf_getAttrib](parent_.data(), symbol_); } }; } // namespace cpp11 diff --git a/inst/include/cpp11/data_frame.hpp b/inst/include/cpp11/data_frame.hpp index 41d47150..15fd9885 100644 --- a/inst/include/cpp11/data_frame.hpp +++ b/inst/include/cpp11/data_frame.hpp @@ -35,8 +35,7 @@ class data_frame : public list { return R_NilValue; } - // @pachadotdev: + noexcept - static R_xlen_t calc_nrow(SEXP x) noexcept { + static R_xlen_t calc_nrow(SEXP x) { auto nms = get_attrib0(x, R_RowNamesSymbol); bool has_short_rownames = (Rf_isInteger(nms) && Rf_xlength(nms) == 2 && INTEGER(nms)[0] == NA_INTEGER); @@ -59,8 +58,8 @@ class data_frame : public list { /* Adapted from * https://github.com/wch/r-source/blob/f2a0dfab3e26fb42b8b296fcba40cbdbdbec767d/src/main/attrib.c#L198-L207 */ - R_xlen_t nrow() const noexcept { return calc_nrow(*this); } - R_xlen_t ncol() const noexcept { return size(); } + R_xlen_t nrow() const { return calc_nrow(*this); } + R_xlen_t ncol() const { return size(); } }; namespace writable { @@ -90,16 +89,15 @@ class data_frame : public cpp11::data_frame { using cpp11::data_frame::ncol; using cpp11::data_frame::nrow; - // @pachadotdev: + noexcept - attribute_proxy attr(const char* name) const noexcept const { + attribute_proxy attr(const char* name) const const { return {*this, name}; } - attribute_proxy attr(const std::string& name) const noexcept { + attribute_proxy attr(const std::string& name) const { return {*this, name.c_str()}; } - attribute_proxy attr(SEXP name) const noexcept { return {*this, name}; } + attribute_proxy attr(SEXP name) const { return {*this, name}; } attribute_proxy names() const { return {*this, R_NamesSymbol}; } }; diff --git a/inst/include/cpp11/doubles.hpp b/inst/include/cpp11/doubles.hpp index aa5c6044..dcab086d 100644 --- a/inst/include/cpp11/doubles.hpp +++ b/inst/include/cpp11/doubles.hpp @@ -16,7 +16,7 @@ namespace cpp11 { template <> -inline constexpr SEXPTYPE r_vector::get_sexptype() { +inline SEXPTYPE r_vector::get_sexptype() { return REALSXP; } diff --git a/inst/include/cpp11/environment.hpp b/inst/include/cpp11/environment.hpp index 2d9ba0c3..eeee9236 100644 --- a/inst/include/cpp11/environment.hpp +++ b/inst/include/cpp11/environment.hpp @@ -48,10 +48,9 @@ class environment { void remove(const char* name) { remove(safe[Rf_install](name)); } - // @pachadotdev: + noexcept - R_xlen_t size() const noexcept { return Rf_xlength(env_); } + R_xlen_t size() const { return Rf_xlength(env_); } - operator SEXP() const noexcept { return env_; } + operator SEXP() const { return env_; } }; } // namespace cpp11 diff --git a/inst/include/cpp11/external_pointer.hpp b/inst/include/cpp11/external_pointer.hpp index 6b63864a..133feab4 100644 --- a/inst/include/cpp11/external_pointer.hpp +++ b/inst/include/cpp11/external_pointer.hpp @@ -12,9 +12,8 @@ namespace cpp11 { -// @pachadotdev: + noexcept template -void default_deleter(T* obj) noexcept { +void default_deleter(T* obj) { delete obj; } @@ -34,8 +33,7 @@ class external_pointer { return data; } - // @pachadotdev: + noexcept - static void r_deleter(SEXP p) noexcept { + static void r_deleter(SEXP p) { if (detail::r_typeof(p) != EXTPTRSXP) return; T* ptr = static_cast(R_ExternalPtrAddr(p)); diff --git a/inst/include/cpp11/integers.hpp b/inst/include/cpp11/integers.hpp index dbf8471e..68fd8e4d 100644 --- a/inst/include/cpp11/integers.hpp +++ b/inst/include/cpp11/integers.hpp @@ -17,7 +17,7 @@ namespace cpp11 { template <> -inline constexpr SEXPTYPE r_vector::get_sexptype() { +inline SEXPTYPE r_vector::get_sexptype() { return INTSXP; } diff --git a/inst/include/cpp11/list.hpp b/inst/include/cpp11/list.hpp index e83614f3..66cd99c7 100644 --- a/inst/include/cpp11/list.hpp +++ b/inst/include/cpp11/list.hpp @@ -14,7 +14,7 @@ namespace cpp11 { template <> -inline constexpr SEXPTYPE r_vector::get_sexptype() { +inline SEXPTYPE r_vector::get_sexptype() { return VECSXP; } diff --git a/inst/include/cpp11/logicals.hpp b/inst/include/cpp11/logicals.hpp index 02bb712c..45d3d1cc 100644 --- a/inst/include/cpp11/logicals.hpp +++ b/inst/include/cpp11/logicals.hpp @@ -16,7 +16,7 @@ namespace cpp11 { template <> -inline constexpr SEXPTYPE r_vector::get_sexptype() { +inline SEXPTYPE r_vector::get_sexptype() { return LGLSXP; } diff --git a/inst/include/cpp11/matrix.hpp b/inst/include/cpp11/matrix.hpp index f7990300..8345068f 100644 --- a/inst/include/cpp11/matrix.hpp +++ b/inst/include/cpp11/matrix.hpp @@ -184,10 +184,9 @@ class matrix : public matrix_slices { SEXP data() const { return vector_.data(); } - // @pachadotdev: + noexcept - R_xlen_t size() const noexcept { return vector_.size(); } + R_xlen_t size() const { return vector_.size(); } - operator SEXP() const noexcept { return SEXP(vector_); } + operator SEXP() const { return SEXP(vector_); } // operator sexp() { return sexp(vector_); } diff --git a/inst/include/cpp11/named_arg.hpp b/inst/include/cpp11/named_arg.hpp index 07183bc8..d27e7e86 100644 --- a/inst/include/cpp11/named_arg.hpp +++ b/inst/include/cpp11/named_arg.hpp @@ -11,8 +11,7 @@ namespace cpp11 { class named_arg { public: - // @pachadotdev: + noexcept - explicit named_arg(const char* name) noexcept : name_(name), value_(R_NilValue) {} + explicit named_arg(const char* name) : name_(name), value_(R_NilValue) {} named_arg& operator=(std::initializer_list il) { value_ = as_sexp(il); return *this; @@ -40,8 +39,7 @@ class named_arg { namespace literals { -// @pachadotdev: + noexcept -inline named_arg operator""_nm(const char* name, std::size_t) noexcept { +inline named_arg operator""_nm(const char* name, std::size_t) { return named_arg(name); } diff --git a/inst/include/cpp11/protect.hpp b/inst/include/cpp11/protect.hpp index dac0dec5..9cb4876a 100644 --- a/inst/include/cpp11/protect.hpp +++ b/inst/include/cpp11/protect.hpp @@ -186,8 +186,7 @@ struct protect { }; constexpr struct protect safe = {}; -// @pachadotdev: + noexcept -inline void check_user_interrupt() noexcept { safe[R_CheckUserInterrupt](); } +inline void check_user_interrupt() { safe[R_CheckUserInterrupt](); } #ifdef CPP11_USE_FMT template diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 8c854116..4973267f 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -65,9 +65,8 @@ class r_vector { r_vector& operator=(const r_vector& rhs); r_vector& operator=(r_vector&& rhs); - // @pachadotdev: + noexcept - operator SEXP() noexcept const; - operator sexp() noexcept const; + operator SEXP() const; + operator sexp() const; #ifdef LONG_VECTOR_SUPPORT T operator[](const int pos) const; @@ -86,10 +85,9 @@ class r_vector { bool contains(const r_string& name) const; bool is_altrep() const; bool named() const; - // @pachadotdev: + noexcept R_xlen_t size() noexcept const; - bool empty() no except const; - SEXP data() noexcept const; + bool empty() const; + SEXP data() const; const sexp attr(const char* name) const; const sexp attr(const std::string& name) const; @@ -97,11 +95,10 @@ class r_vector { r_vector names() const; - // @pachadotdev: + noexcept - const_iterator begin() noexcept const; - const_iterator end() noexcept const; - const_iterator cbegin() noexcept const; - const_iterator cend() noexcept const; + const_iterator begin() const; + const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; const_iterator find(const r_string& name) const; class const_iterator { @@ -451,15 +448,13 @@ inline r_vector& r_vector::operator=(r_vector&& rhs) { return *this; } -// @pachadotdev: + noexcept template -inline r_vector::operator SEXP() const noexcept { +inline r_vector::operator SEXP() const { return data_; } -// @pachadotdev: + noexcept template -inline r_vector::operator sexp() const noexcept { +inline r_vector::operator sexp() const { return data_; } @@ -641,27 +636,23 @@ inline SEXP r_vector::valid_length(SEXP x, R_xlen_t n) { throw std::length_error(message); } -// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::begin() const noexcept { +inline typename r_vector::const_iterator r_vector::begin() const { return const_iterator(this, 0); } -// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::end() const noexcept { +inline typename r_vector::const_iterator r_vector::end() const { return const_iterator(this, length_); } -// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::cbegin() const noexcept { +inline typename r_vector::const_iterator r_vector::cbegin() const { return const_iterator(this, 0); } -// @pachadotdev: + noexcept template -inline typename r_vector::const_iterator r_vector::cend() const noexcept { +inline typename r_vector::const_iterator r_vector::cend() const { return const_iterator(this, length_); } @@ -1079,9 +1070,8 @@ inline void r_vector::push_back(T value) { ++length_; } -// @pachadotdev: + noexcept template -inline void r_vector::pop_back() noexcept { +inline void r_vector::pop_back() { --length_; } @@ -1138,7 +1128,7 @@ inline typename r_vector::iterator r_vector::erase(R_xlen_t pos) { } template -inline void r_vector::clear() noexcept { +inline void r_vector::clear() { length_ = 0; } diff --git a/inst/include/cpp11/raws.hpp b/inst/include/cpp11/raws.hpp index 9ee2dbc0..f0ad9dcd 100644 --- a/inst/include/cpp11/raws.hpp +++ b/inst/include/cpp11/raws.hpp @@ -67,10 +67,9 @@ typedef r_vector raws; namespace writable { -// @pachadotdev: + noexcept template <> inline void r_vector::set_elt( - SEXP x, R_xlen_t i, typename r_vector::underlying_type value) noexcept { + SEXP x, R_xlen_t i, typename r_vector::underlying_type value) { // NOPROTECT: Likely too costly to unwind protect every set elt #if R_VERSION >= R_Version(4, 2, 0) SET_RAW_ELT(x, i, value); diff --git a/inst/include/cpp11/sexp.hpp b/inst/include/cpp11/sexp.hpp index 2f1344e1..11ff8273 100644 --- a/inst/include/cpp11/sexp.hpp +++ b/inst/include/cpp11/sexp.hpp @@ -64,17 +64,15 @@ class sexp { return attribute_proxy(*this, R_NamesSymbol); } - // @pachadotdev: + noexcept - operator SEXP() const noexcept { return data_; } - SEXP data() const noexcept { return data_; } + operator SEXP() const { return data_; } + SEXP data() const { return data_; } - // @pachadotdev: + noexcept /// DEPRECATED: Do not use this, it will be removed soon. - operator double() const noexcept { return REAL_ELT(data_, 0); } + operator double() const { return REAL_ELT(data_, 0); } /// DEPRECATED: Do not use this, it will be removed soon. - operator size_t() const noexcept { returnv REAL_ELT(data_, 0); } + operator size_t() const { returnv REAL_ELT(data_, 0); } /// DEPRECATED: Do not use this, it will be removed soon. - operator bool() const noexcept { return LOGICAL_ELT(data_, 0); } + operator bool() const { return LOGICAL_ELT(data_, 0); } }; } // namespace cpp11 From 8fdaaef06b935e150469f3fdf88fbac0d2dd4f4d Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 19:12:03 -0400 Subject: [PATCH 09/14] clang format --- inst/include/cpp11/data_frame.hpp | 4 +--- inst/include/cpp11/named_arg.hpp | 4 +--- inst/include/cpp11/raws.hpp | 4 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/inst/include/cpp11/data_frame.hpp b/inst/include/cpp11/data_frame.hpp index 15fd9885..8d337ef3 100644 --- a/inst/include/cpp11/data_frame.hpp +++ b/inst/include/cpp11/data_frame.hpp @@ -89,9 +89,7 @@ class data_frame : public cpp11::data_frame { using cpp11::data_frame::ncol; using cpp11::data_frame::nrow; - attribute_proxy attr(const char* name) const const { - return {*this, name}; - } + attribute_proxy attr(const char* name) const const { return {*this, name}; } attribute_proxy attr(const std::string& name) const { return {*this, name.c_str()}; diff --git a/inst/include/cpp11/named_arg.hpp b/inst/include/cpp11/named_arg.hpp index d27e7e86..df7ba935 100644 --- a/inst/include/cpp11/named_arg.hpp +++ b/inst/include/cpp11/named_arg.hpp @@ -39,9 +39,7 @@ class named_arg { namespace literals { -inline named_arg operator""_nm(const char* name, std::size_t) { - return named_arg(name); -} +inline named_arg operator""_nm(const char* name, std::size_t) { return named_arg(name); } } // namespace literals diff --git a/inst/include/cpp11/raws.hpp b/inst/include/cpp11/raws.hpp index f0ad9dcd..f16a6e39 100644 --- a/inst/include/cpp11/raws.hpp +++ b/inst/include/cpp11/raws.hpp @@ -68,8 +68,8 @@ typedef r_vector raws; namespace writable { template <> -inline void r_vector::set_elt( - SEXP x, R_xlen_t i, typename r_vector::underlying_type value) { +inline void r_vector::set_elt(SEXP x, R_xlen_t i, + typename r_vector::underlying_type value) { // NOPROTECT: Likely too costly to unwind protect every set elt #if R_VERSION >= R_Version(4, 2, 0) SET_RAW_ELT(x, i, value); From a80ae9104375d7edd8be1e80de9c067707a3bf60 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 19:13:38 -0400 Subject: [PATCH 10/14] fix typos --- inst/include/cpp11/data_frame.hpp | 2 +- inst/include/cpp11/r_bool.hpp | 3 +-- inst/include/cpp11/sexp.hpp | 2 +- inst/include/cpp11/strings.hpp | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/inst/include/cpp11/data_frame.hpp b/inst/include/cpp11/data_frame.hpp index 8d337ef3..6be16400 100644 --- a/inst/include/cpp11/data_frame.hpp +++ b/inst/include/cpp11/data_frame.hpp @@ -89,7 +89,7 @@ class data_frame : public cpp11::data_frame { using cpp11::data_frame::ncol; using cpp11::data_frame::nrow; - attribute_proxy attr(const char* name) const const { return {*this, name}; } + attribute_proxy attr(const char* name) const { return {*this, name}; } attribute_proxy attr(const std::string& name) const { return {*this, name.c_str()}; diff --git a/inst/include/cpp11/r_bool.hpp b/inst/include/cpp11/r_bool.hpp index f11b111d..4ea36da8 100644 --- a/inst/include/cpp11/r_bool.hpp +++ b/inst/include/cpp11/r_bool.hpp @@ -66,9 +66,8 @@ enable_if_r_bool as_sexp(T from) { return res; } -// @pachadotdev: + noexcept template <> -inline r_bool na() noexcept { +inline r_bool na() { return NA_LOGICAL; } diff --git a/inst/include/cpp11/sexp.hpp b/inst/include/cpp11/sexp.hpp index 11ff8273..74205e69 100644 --- a/inst/include/cpp11/sexp.hpp +++ b/inst/include/cpp11/sexp.hpp @@ -70,7 +70,7 @@ class sexp { /// DEPRECATED: Do not use this, it will be removed soon. operator double() const { return REAL_ELT(data_, 0); } /// DEPRECATED: Do not use this, it will be removed soon. - operator size_t() const { returnv REAL_ELT(data_, 0); } + operator size_t() const { return REAL_ELT(data_, 0); } /// DEPRECATED: Do not use this, it will be removed soon. operator bool() const { return LOGICAL_ELT(data_, 0); } }; diff --git a/inst/include/cpp11/strings.hpp b/inst/include/cpp11/strings.hpp index 22253066..5bf76e4e 100644 --- a/inst/include/cpp11/strings.hpp +++ b/inst/include/cpp11/strings.hpp @@ -17,7 +17,7 @@ namespace cpp11 { template <> -inline constexpr SEXPTYPE r_vector::get_sexptype() { +inline SEXPTYPE r_vector::get_sexptype() { return STRSXP; } From ff8e314b14df75fe49877f470981ff5aee7a5ef7 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 19:14:34 -0400 Subject: [PATCH 11/14] fix r_Vector --- inst/include/cpp11/r_vector.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 4973267f..b2e512fe 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -85,7 +85,7 @@ class r_vector { bool contains(const r_string& name) const; bool is_altrep() const; bool named() const; - R_xlen_t size() noexcept const; + R_xlen_t size() const; bool empty() const; SEXP data() const; From f7fd0e05d8a0f46e3c5c9d6c13b9a7b3fcf09047 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 19:23:42 -0400 Subject: [PATCH 12/14] fix strings --- inst/include/cpp11/strings.hpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/inst/include/cpp11/strings.hpp b/inst/include/cpp11/strings.hpp index 5bf76e4e..61ccf15b 100644 --- a/inst/include/cpp11/strings.hpp +++ b/inst/include/cpp11/strings.hpp @@ -137,17 +137,10 @@ typedef r_vector strings; // 2nd, 3rd, ..., Nth name: reserve exactly one more, then emplace template inline void r_vector::push_back(const named_arg& value) { - push_back(value.value()); - cpp11::writable::strings nms(names()); - if (nms.size() == 0) { - nms.reserve(1); - nms.emplace_back(value.name()); - } else { - nms.reserve(nms.size() + 1); - nms.emplace_back(value.name()); - } + nms.reserve(nms.size() + 1); + nms.push_back(value.name()); names() = nms; } From e0229d54faccbffe557581fc0d234251fb6998a9 Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 19:31:11 -0400 Subject: [PATCH 13/14] rollback strings --- inst/include/cpp11/strings.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/inst/include/cpp11/strings.hpp b/inst/include/cpp11/strings.hpp index 61ccf15b..8b788464 100644 --- a/inst/include/cpp11/strings.hpp +++ b/inst/include/cpp11/strings.hpp @@ -137,12 +137,13 @@ typedef r_vector strings; // 2nd, 3rd, ..., Nth name: reserve exactly one more, then emplace template inline void r_vector::push_back(const named_arg& value) { + push_back(value.value()); + if (Rf_xlength(names()) == 0) { + cpp11::writable::strings new_nms(size()); + names() = new_nms; + } cpp11::writable::strings nms(names()); - - nms.reserve(nms.size() + 1); - nms.push_back(value.name()); - - names() = nms; + nms[size() - 1] = value.name(); } } // namespace writable From ddf53006b13101e8101beafef04f51aca2e4e3ea Mon Sep 17 00:00:00 2001 From: Mauricio 'Pacha' Vargas Sepulveda Date: Fri, 9 May 2025 19:31:56 -0400 Subject: [PATCH 14/14] rollback strings --- inst/include/cpp11/strings.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/inst/include/cpp11/strings.hpp b/inst/include/cpp11/strings.hpp index 8b788464..393f2a8c 100644 --- a/inst/include/cpp11/strings.hpp +++ b/inst/include/cpp11/strings.hpp @@ -132,9 +132,6 @@ inline r_vector::r_vector(std::initializer_list il) typedef r_vector strings; -// @pachadotdev: -// 1st name - reserve one slot, then emplace -// 2nd, 3rd, ..., Nth name: reserve exactly one more, then emplace template inline void r_vector::push_back(const named_arg& value) { push_back(value.value()); @@ -145,6 +142,7 @@ inline void r_vector::push_back(const named_arg& value) { cpp11::writable::strings nms(names()); nms[size() - 1] = value.name(); } + } // namespace writable } // namespace cpp11