diff --git a/ChangeLog b/ChangeLog index dfce30f37..2370d94fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2021-01-19 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll minor version + * inst/include/Rcpp/config.h: Idem + + * inst/include/RcppCommon.h: Preverse existing API and offer new + token-based API alongside via Rcpp_Precious{Preserve,Release} + * inst/include/Rcpp/String.h: Use Rcpp_Precious{Preserve,Release} + * inst/include/Rcpp/storage/PreserveStorage.h: Ditto + 2021-01-17 IƱaki Ucar * inst/include/Rcpp/String.h: Use Rcpp_{Preserve,Release}Object diff --git a/DESCRIPTION b/DESCRIPTION index 7e7531592..8715c0cbf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: Rcpp Title: Seamless R and C++ Integration -Version: 1.0.6.2 -Date: 2021-01-17 +Version: 1.0.6.3 +Date: 2021-01-19 Author: Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey, Qiang Kou, Nathan Russell, Douglas Bates and John Chambers Maintainer: Dirk Eddelbuettel diff --git a/inst/include/Rcpp/String.h b/inst/include/Rcpp/String.h index cff9b5e1f..973ebed66 100644 --- a/inst/include/Rcpp/String.h +++ b/inst/include/Rcpp/String.h @@ -53,13 +53,13 @@ namespace Rcpp { /** default constructor */ String(): data(Rf_mkCharCE("", CE_UTF8)), token(R_NilValue), buffer(), valid(true), buffer_ready(true), enc(CE_UTF8) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); RCPP_STRING_DEBUG("String()"); } /** copy constructor */ String(const String& other) : data(other.get_sexp()), token(R_NilValue), valid(true), buffer_ready(false), enc(Rf_getCharCE(other.get_sexp())) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); RCPP_STRING_DEBUG("String(const String&)"); } @@ -82,30 +82,30 @@ namespace Rcpp { valid = true; buffer_ready = false; enc = Rf_getCharCE(data); - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); RCPP_STRING_DEBUG("String(SEXP)"); } /** from string proxy */ String(const StringProxy& proxy): data(proxy.get()), token(R_NilValue), valid(true), buffer_ready(false), enc(Rf_getCharCE(proxy.get())) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); RCPP_STRING_DEBUG("String(const StringProxy&)"); } String(const StringProxy& proxy, cetype_t enc): data(proxy.get()), token(R_NilValue), valid(true), buffer_ready(false) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); set_encoding(enc); RCPP_STRING_DEBUG("String(const StringProxy&, cetype_t)"); } /** from string proxy */ String(const const_StringProxy& proxy): data(proxy.get()), token(R_NilValue), valid(true), buffer_ready(false), enc(Rf_getCharCE(proxy.get())) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); RCPP_STRING_DEBUG("String(const const_StringProxy&)"); } String(const const_StringProxy& proxy, cetype_t enc): data(proxy.get()), token(R_NilValue), valid(true), buffer_ready(false) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); set_encoding(enc); RCPP_STRING_DEBUG("String(const const_StringProxy&, cetype_t)"); } @@ -118,7 +118,7 @@ namespace Rcpp { } String(const std::wstring& s, cetype_t enc = CE_UTF8) : data(internal::make_charsexp(s)), token(R_NilValue), valid(true), buffer_ready(false), enc(enc) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); RCPP_STRING_DEBUG("String(const std::wstring&, cetype_t)"); } @@ -130,29 +130,29 @@ namespace Rcpp { } String(const wchar_t* s, cetype_t enc = CE_UTF8) : data(internal::make_charsexp(s)), token(R_NilValue), valid(true), buffer_ready(false), enc(enc) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); RCPP_STRING_DEBUG("String(const wchar_t* s, cetype_t)"); } /** constructors from R primitives */ String(int x) : data(internal::r_coerce(x)), token(R_NilValue), valid(true), buffer_ready(false), enc(CE_UTF8) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); } String(double x) : data(internal::r_coerce(x)), token(R_NilValue), valid(true), buffer_ready(false), enc(CE_UTF8) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); } String(bool x) : data(internal::r_coerce(x)), token(R_NilValue), valid(true) , buffer_ready(false), enc(CE_UTF8) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); } String(Rcomplex x) : data(internal::r_coerce(x)), token(R_NilValue), valid(true), buffer_ready(false), enc(CE_UTF8) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); } String(Rbyte x) : data(internal::r_coerce(x)), token(R_NilValue), valid(true), buffer_ready(false), enc(CE_UTF8) { - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); } ~String() { - Rcpp_ReleaseObject(token); + Rcpp_PreciousRelease(token); data = R_NilValue; token = R_NilValue; } @@ -160,40 +160,40 @@ namespace Rcpp { inline String& operator=(int x) { data = internal::r_coerce(x); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; } inline String& operator=(double x) { data = internal::r_coerce(x); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; } inline String& operator=(Rbyte x) { data = internal::r_coerce(x); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; } inline String& operator=(bool x) { data = internal::r_coerce(x); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; } inline String& operator=(Rcomplex x) { data = internal::r_coerce(x); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; @@ -201,8 +201,8 @@ namespace Rcpp { inline String& operator=(SEXP x) { if (data != x) { data = x; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); } valid = true; buffer_ready = false; @@ -212,8 +212,8 @@ namespace Rcpp { SEXP x = proxy.get(); if (data != x) { data = x; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(x); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(x); } valid = true; buffer_ready = false; @@ -223,8 +223,8 @@ namespace Rcpp { SEXP x = other.get_sexp(); if (data != x) { data = x; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(x); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(x); } valid = true; buffer_ready = false; @@ -247,8 +247,8 @@ namespace Rcpp { template inline String& assign_wide_string(const T& s) { data = internal::make_charsexp(s); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; @@ -281,8 +281,8 @@ namespace Rcpp { std::wstring tmp(buf, buf + strlen(buf)); tmp += s; data = internal::make_charsexp(tmp); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; @@ -298,8 +298,8 @@ namespace Rcpp { if (is_na()) return *this; if (other.is_na()) { data = NA_STRING; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; @@ -313,8 +313,8 @@ namespace Rcpp { SEXP proxy_sexp = proxy; if (proxy_sexp == NA_STRING) { data = NA_STRING; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; @@ -328,8 +328,8 @@ namespace Rcpp { SEXP proxy_sexp = proxy; if (proxy_sexp == NA_STRING) { data = NA_STRING; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; @@ -342,8 +342,8 @@ namespace Rcpp { if (is_na()) return *this; if (x == NA_STRING) { data = NA_STRING; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; return *this; @@ -479,8 +479,8 @@ namespace Rcpp { inline void set_na() { data = NA_STRING; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); valid = true; buffer_ready = false; } @@ -533,11 +533,11 @@ namespace Rcpp { // TODO: may longjmp on failure to translate? const char* translated = Rf_translateCharUTF8(data); data = Rf_mkCharCE(translated, encoding); - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); } else { data = get_sexp_impl(); - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); valid = true; } } @@ -610,7 +610,7 @@ namespace Rcpp { RCPP_STRING_DEBUG("setData"); if (!valid) { data = get_sexp_impl(); - token = Rcpp_PreserveObject(data); + token = Rcpp_PreciousPreserve(data); valid = true; } } diff --git a/inst/include/Rcpp/config.h b/inst/include/Rcpp/config.h index 277893503..5182b0913 100644 --- a/inst/include/Rcpp/config.h +++ b/inst/include/Rcpp/config.h @@ -30,7 +30,7 @@ #define RCPP_VERSION_STRING "1.0.6" // the current source snapshot -#define RCPP_DEV_VERSION RcppDevVersion(1,0,6,2) -#define RCPP_DEV_VERSION_STRING "1.0.6.2" +#define RCPP_DEV_VERSION RcppDevVersion(1,0,6,3) +#define RCPP_DEV_VERSION_STRING "1.0.6.3" #endif diff --git a/inst/include/Rcpp/storage/PreserveStorage.h b/inst/include/Rcpp/storage/PreserveStorage.h index 7d069eeb1..84e41dc77 100644 --- a/inst/include/Rcpp/storage/PreserveStorage.h +++ b/inst/include/Rcpp/storage/PreserveStorage.h @@ -31,7 +31,7 @@ namespace Rcpp{ PreserveStorage() : data(R_NilValue), token(R_NilValue){} ~PreserveStorage(){ - Rcpp_ReleaseObject(token) ; + Rcpp_PreciousRelease(token) ; data = R_NilValue; token = R_NilValue; } @@ -39,8 +39,8 @@ namespace Rcpp{ inline void set__(SEXP x){ if (data != x) { data = x; - Rcpp_ReleaseObject(token); - token = Rcpp_PreserveObject(data); + Rcpp_PreciousRelease(token); + token = Rcpp_PreciousPreserve(data); } // calls the update method of CLASS @@ -54,7 +54,7 @@ namespace Rcpp{ inline SEXP invalidate__(){ SEXP out = data ; - Rcpp_ReleaseObject(token); + Rcpp_PreciousRelease(token); data = R_NilValue ; token = R_NilValue ; return out ; diff --git a/inst/include/Rcpp/traits/named_object.h b/inst/include/Rcpp/traits/named_object.h index 188c03742..60eec15c3 100644 --- a/inst/include/Rcpp/traits/named_object.h +++ b/inst/include/Rcpp/traits/named_object.h @@ -41,15 +41,15 @@ template <> class named_object { public: // #nocov start named_object( const std::string& name_, const SEXP& o_): name(name_), object(o_), token(R_NilValue) { - token = Rcpp_precious_preserve(object); + token = Rcpp_PreciousPreserve(object); } named_object( const named_object& other ) : name(other.name), object(other.object), token(other.token) { - token = Rcpp_precious_preserve(object); + token = Rcpp_PreciousPreserve(object); } ~named_object() { - Rcpp_precious_remove(token); + Rcpp_PreciousRelease(token); } // #nocov end const std::string& name; diff --git a/inst/include/RcppCommon.h b/inst/include/RcppCommon.h index fbaeaf8e9..413be7004 100644 --- a/inst/include/RcppCommon.h +++ b/inst/include/RcppCommon.h @@ -91,11 +91,31 @@ namespace Rcpp { template class named_object; } - inline SEXP Rcpp_PreserveObject(SEXP object) { + // begin deprecated interface not using precious list + // use Rcpp_PreciousPreserve + Rcpp_PreciousRelease below it + inline SEXP Rcpp_PreserveObject(SEXP x) { + if (x != R_NilValue) R_PreserveObject(x); + return x; + } + inline void Rcpp_ReleaseObject(SEXP x) { + if (x != R_NilValue) R_ReleaseObject(x); + } + inline SEXP Rcpp_ReplaceObject(SEXP x, SEXP y) { + // if we are setting to the same SEXP as we already have, do nothing + if (x != y) { + Rcpp_ReleaseObject(x); + Rcpp_PreserveObject(y); + } + return y; + } + // end deprecated interface not using precious list + + // new preferred interface using token-based precious list + inline SEXP Rcpp_PreciousPreserve(SEXP object) { return Rcpp_precious_preserve(object); } - inline void Rcpp_ReleaseObject(SEXP token) { + inline void Rcpp_PreciousRelease(SEXP token) { Rcpp_precious_remove(token); }