Skip to content

as_sexp_strings() could use a single unwind_protect() around the loop #460

@DavisVaughan

Description

@DavisVaughan

To convert from std::vector<std::string> to cpp11::strings you might do cpp11::strings(as_sexp(x)). That goes through as_sexp_strings() which looks like it could be a little more efficient. Rather than calling safe[Rf_mkCharCE] on each iteration, I think we could wrap the whole loop in a single unwind_protect().

SEXP as_sexp_strings(const Container& from, AsCstring&& c_str) {
R_xlen_t size = from.size();
SEXP data;
try {
data = PROTECT(safe[Rf_allocVector](STRSXP, size));
auto it = from.begin();
for (R_xlen_t i = 0; i < size; ++i, ++it) {
SET_STRING_ELT(data, i, safe[Rf_mkCharCE](c_str(*it), CE_UTF8));
}
} catch (const unwind_exception& e) {
UNPROTECT(1);
throw e;
}
UNPROTECT(1);
return data;
}
} // namespace detail

Something like

cpp11/vignettes/FAQ.Rmd

Lines 499 to 503 in 05c888b

cpp11::unwind_protect([&] {
for (R_xlen_t i = 0; i < size; ++i) {
(void) STRING_ELT(data, i);
}
});

Be careful to avoid all the pitfalls of calling unwind_protect() manually that are mentioned in that vignette

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions