Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions inst/include/cpp11/protect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,26 +281,20 @@ inline SEXP insert(SEXP x) {
return R_NilValue;
}

PROTECT(x);

SEXP list = get();

// Get references to the head of the preserve list and the next element
// after the head
SEXP head = list;
SEXP next = CDR(list);

// Add a new cell that points to the current head + next.
SEXP cell = PROTECT(Rf_cons(head, next));
// Create the new cell
SEXP cell = Rf_cons(head, next);
SET_TAG(cell, x);

// Update the head + next to point at the newly-created cell,
// effectively inserting that cell between the current head + next.
// Update the list structure
SETCDR(head, cell);
SETCAR(next, cell);

UNPROTECT(2);

return cell;
}

Expand Down
23 changes: 9 additions & 14 deletions inst/include/cpp11/r_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,16 +1320,17 @@ inline typename r_vector<T>::iterator r_vector<T>::iterator::operator+(R_xlen_t
template <typename T>
inline SEXP r_vector<T>::reserve_data(SEXP x, bool is_altrep, R_xlen_t size) {
// Resize core data
SEXP out = PROTECT(resize_data(x, is_altrep, size));
SEXP out = resize_data(x, is_altrep, size);

// Resize names, if required
// Protection seems needed to make rchk happy
SEXP names = PROTECT(Rf_getAttrib(x, R_NamesSymbol));
SEXP names = Rf_getAttrib(x, R_NamesSymbol);
if (names != R_NilValue) {
if (Rf_xlength(names) != size) {
names = resize_names(names, size);
SEXP new_names = resize_names(names, size);
Rf_setAttrib(out, R_NamesSymbol, new_names);
} else {
Rf_setAttrib(out, R_NamesSymbol, names);
}
Rf_setAttrib(out, R_NamesSymbol, names);
}

// Copy over "most" attributes, and set OBJECT bit and S4 bit as needed.
Expand All @@ -1338,16 +1339,14 @@ inline SEXP r_vector<T>::reserve_data(SEXP x, bool is_altrep, R_xlen_t size) {
// as this is a vector.
// Does not look like it would ever error in our use cases, so no `safe[]`.
Rf_copyMostAttrib(x, out);

UNPROTECT(2);
return out;
}

template <typename T>
inline SEXP r_vector<T>::resize_data(SEXP x, bool is_altrep, R_xlen_t size) {
underlying_type const* v_x = get_const_p(is_altrep, x);

SEXP out = PROTECT(safe[Rf_allocVector](get_sexptype(), size));
SEXP out = safe[Rf_allocVector](get_sexptype(), size);
underlying_type* v_out = get_p(ALTREP(out), out);

const R_xlen_t x_size = Rf_xlength(x);
Expand All @@ -1364,29 +1363,25 @@ inline SEXP r_vector<T>::resize_data(SEXP x, bool is_altrep, R_xlen_t size) {
}
}

UNPROTECT(1);
return out;
}

template <typename T>
inline SEXP r_vector<T>::resize_names(SEXP x, R_xlen_t size) {
const SEXP* v_x = STRING_PTR_RO(x);

SEXP out = PROTECT(safe[Rf_allocVector](STRSXP, size));
SEXP out = safe[Rf_allocVector](STRSXP, size);

const R_xlen_t x_size = Rf_xlength(x);
const R_xlen_t copy_size = (x_size > size) ? size : x_size;

for (R_xlen_t i = 0; i < copy_size; ++i) {
SET_STRING_ELT(out, i, v_x[i]);
SET_STRING_ELT(out, i, STRING_ELT(x, i));
}

// Ensure remaining names are initialized to `""`
for (R_xlen_t i = copy_size; i < size; ++i) {
SET_STRING_ELT(out, i, R_BlankString);
}

UNPROTECT(1);
return out;
}

Expand Down