Skip to content

Commit

Permalink
Create internal store namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
DavisVaughan committed Jul 28, 2024
1 parent 7508f2c commit 9b5f6dd
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 73 deletions.
8 changes: 4 additions & 4 deletions cpp11test/src/protect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

[[cpp11::register]] void protect_one_cpp11_(SEXP x, int n) {
for (R_xlen_t i = 0; i < n; ++i) {
SEXP p = cpp11::detail::store_insert(x);
cpp11::detail::store_release(p);
SEXP p = cpp11::detail::store::insert(x);
cpp11::detail::store::release(p);
}
}

Expand Down Expand Up @@ -51,12 +51,12 @@
[[cpp11::register]] void protect_many_cpp11_(int n) {
std::vector<SEXP> res;
for (R_xlen_t i = 0; i < n; ++i) {
res.push_back(cpp11::detail::store_insert(Rf_ScalarInteger(n)));
res.push_back(cpp11::detail::store::insert(Rf_ScalarInteger(n)));
}

for (R_xlen_t i = n - 1; i >= 0; --i) {
SEXP x = res[i];
cpp11::detail::store_release(x);
cpp11::detail::store::release(x);
res.pop_back();
}
}
Expand Down
8 changes: 4 additions & 4 deletions inst/include/cpp11/doubles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ template <>
inline r_vector<double>::r_vector(std::initializer_list<named_arg> il)
: cpp11::r_vector<double>(safe[Rf_allocVector](REALSXP, il.size())),
capacity_(il.size()) {
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);
int n_protected = 0;

try {
Expand All @@ -100,7 +100,7 @@ inline r_vector<double>::r_vector(std::initializer_list<named_arg> il)
UNPROTECT(n_protected);
});
} catch (const unwind_exception& e) {
detail::store_release(protect_);
detail::store::release(protect_);
UNPROTECT(n_protected);
throw e;
}
Expand All @@ -111,8 +111,8 @@ inline void r_vector<double>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](REALSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);
SEXP old_protect = protect_;
protect_ = detail::store_insert(data_);
detail::store_release(old_protect);
protect_ = detail::store::insert(data_);
detail::store::release(old_protect);

data_p_ = REAL(data_);
capacity_ = new_capacity;
Expand Down
10 changes: 5 additions & 5 deletions inst/include/cpp11/integers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "cpp11/as.hpp" // for as_sexp
#include "cpp11/attribute_proxy.hpp" // for attribute_proxy
#include "cpp11/named_arg.hpp" // for named_arg
#include "cpp11/protect.hpp" // for store_insert, store_release
#include "cpp11/protect.hpp" // for store
#include "cpp11/r_vector.hpp" // for r_vector, r_vector<>::proxy
#include "cpp11/sexp.hpp" // for sexp

Expand Down Expand Up @@ -87,10 +87,10 @@ inline void r_vector<int>::reserve(R_xlen_t new_capacity) {
SEXP old_protect = protect_;

// Protect the new data
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);

// Release the old protection;
detail::store_release(old_protect);
detail::store::release(old_protect);

data_p_ = INTEGER(data_);
capacity_ = new_capacity;
Expand All @@ -100,7 +100,7 @@ template <>
inline r_vector<int>::r_vector(std::initializer_list<named_arg> il)
: cpp11::r_vector<int>(safe[Rf_allocVector](INTSXP, il.size())),
capacity_(il.size()) {
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);
int n_protected = 0;

try {
Expand All @@ -116,7 +116,7 @@ inline r_vector<int>::r_vector(std::initializer_list<named_arg> il)
UNPROTECT(n_protected);
});
} catch (const unwind_exception& e) {
detail::store_release(protect_);
detail::store::release(protect_);
UNPROTECT(n_protected);
throw e;
}
Expand Down
12 changes: 6 additions & 6 deletions inst/include/cpp11/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "cpp11/R.hpp" // for SEXP, SEXPREC, SET_VECTOR_ELT
#include "cpp11/attribute_proxy.hpp" // for attribute_proxy
#include "cpp11/named_arg.hpp" // for named_arg
#include "cpp11/protect.hpp" // for store_insert, store_release
#include "cpp11/protect.hpp" // for store
#include "cpp11/r_string.hpp" // for r_string
#include "cpp11/r_vector.hpp" // for r_vector, r_vector<>::proxy
#include "cpp11/sexp.hpp" // for sexp
Expand Down Expand Up @@ -78,7 +78,7 @@ template <>
inline r_vector<SEXP>::r_vector(std::initializer_list<SEXP> il)
: cpp11::r_vector<SEXP>(safe[Rf_allocVector](VECSXP, il.size())),
capacity_(il.size()) {
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);
auto it = il.begin();
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
SET_VECTOR_ELT(data_, i, *it);
Expand All @@ -89,7 +89,7 @@ template <>
inline r_vector<SEXP>::r_vector(std::initializer_list<named_arg> il)
: cpp11::r_vector<SEXP>(safe[Rf_allocVector](VECSXP, il.size())),
capacity_(il.size()) {
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);
int n_protected = 0;

try {
Expand All @@ -105,7 +105,7 @@ inline r_vector<SEXP>::r_vector(std::initializer_list<named_arg> il)
UNPROTECT(n_protected);
});
} catch (const unwind_exception& e) {
detail::store_release(protect_);
detail::store::release(protect_);
UNPROTECT(n_protected);
throw e;
}
Expand All @@ -117,8 +117,8 @@ inline void r_vector<SEXP>::reserve(R_xlen_t new_capacity) {
: safe[Rf_xlengthgets](data_, new_capacity);

SEXP old_protect = protect_;
protect_ = detail::store_insert(data_);
detail::store_release(old_protect);
protect_ = detail::store::insert(data_);
detail::store::release(old_protect);

capacity_ = new_capacity;
}
Expand Down
12 changes: 6 additions & 6 deletions inst/include/cpp11/logicals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "cpp11/R.hpp" // for SEXP, SEXPREC, Rf_all...
#include "cpp11/attribute_proxy.hpp" // for attribute_proxy
#include "cpp11/named_arg.hpp" // for named_arg
#include "cpp11/protect.hpp" // for store_insert, store_release
#include "cpp11/protect.hpp" // for store
#include "cpp11/r_bool.hpp" // for r_bool
#include "cpp11/r_vector.hpp" // for r_vector, r_vector<>::proxy
#include "cpp11/sexp.hpp" // for sexp
Expand Down Expand Up @@ -80,7 +80,7 @@ inline bool operator==(const r_vector<r_bool>::proxy& lhs, r_bool rhs) {
template <>
inline r_vector<r_bool>::r_vector(std::initializer_list<r_bool> il)
: cpp11::r_vector<r_bool>(Rf_allocVector(LGLSXP, il.size())), capacity_(il.size()) {
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);
auto it = il.begin();
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
SET_LOGICAL_ELT(data_, i, *it);
Expand All @@ -91,7 +91,7 @@ template <>
inline r_vector<r_bool>::r_vector(std::initializer_list<named_arg> il)
: cpp11::r_vector<r_bool>(safe[Rf_allocVector](LGLSXP, il.size())),
capacity_(il.size()) {
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);
int n_protected = 0;

try {
Expand All @@ -107,7 +107,7 @@ inline r_vector<r_bool>::r_vector(std::initializer_list<named_arg> il)
UNPROTECT(n_protected);
});
} catch (const unwind_exception& e) {
detail::store_release(protect_);
detail::store::release(protect_);
UNPROTECT(n_protected);
throw e;
}
Expand All @@ -118,9 +118,9 @@ inline void r_vector<r_bool>::reserve(R_xlen_t new_capacity) {
data_ = data_ == R_NilValue ? safe[Rf_allocVector](LGLSXP, new_capacity)
: safe[Rf_xlengthgets](data_, new_capacity);
SEXP old_protect = protect_;
protect_ = detail::store_insert(data_);
protect_ = detail::store::insert(data_);

detail::store_release(old_protect);
detail::store::release(old_protect);

data_p_ = LOGICAL(data_);
capacity_ = new_capacity;
Expand Down
26 changes: 18 additions & 8 deletions inst/include/cpp11/protect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,28 +265,36 @@ namespace detail {
//
// > A static local variable in an extern inline function always refers to the
// same object. 7.1.2/4 - C++98/C++14 (n3797)
namespace store {

inline SEXP new_store() {
inline SEXP init() {
SEXP out = Rf_cons(R_NilValue, Rf_cons(R_NilValue, R_NilValue));
R_PreserveObject(out);
return out;
}

inline SEXP store() {
inline SEXP get() {
// Note the `static` local variable in the inline extern function here! Guarantees we
// have 1 unique preserve list across all compilation units in the package.
static SEXP out = new_store();
static SEXP out = init();
return out;
}

inline SEXP store_insert(SEXP x) {
inline R_xlen_t count() {
const R_xlen_t head = 1;
const R_xlen_t tail = 1;
SEXP list = get();
return Rf_xlength(list) - head - tail;
}

inline SEXP insert(SEXP x) {
if (x == R_NilValue) {
return R_NilValue;
}

PROTECT(x);

SEXP list = store();
SEXP list = get();

// Get references to the head of the preserve list and the next element
// after the head
Expand All @@ -307,7 +315,7 @@ inline SEXP store_insert(SEXP x) {
return cell;
}

inline void store_release(SEXP cell) {
inline void release(SEXP cell) {
if (cell == R_NilValue) {
return;
}
Expand All @@ -323,8 +331,8 @@ inline void store_release(SEXP cell) {
SETCAR(rhs, lhs);
}

inline void store_print() {
SEXP list = store();
inline void print() {
SEXP list = get();
for (SEXP cell = list; cell != R_NilValue; cell = CDR(cell)) {
REprintf("%p CAR: %p CDR: %p TAG: %p\n", reinterpret_cast<void*>(cell),
reinterpret_cast<void*>(CAR(cell)), reinterpret_cast<void*>(CDR(cell)),
Expand All @@ -333,6 +341,8 @@ inline void store_print() {
REprintf("---\n");
}

} // namespace store

} // namespace detail

} // namespace cpp11
Loading

0 comments on commit 9b5f6dd

Please sign in to comment.