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::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
To convert from
std::vector<std::string>tocpp11::stringsyou might docpp11::strings(as_sexp(x)). That goes throughas_sexp_strings()which looks like it could be a little more efficient. Rather than callingsafe[Rf_mkCharCE]on each iteration, I think we could wrap the whole loop in a singleunwind_protect().cpp11/inst/include/cpp11/as.hpp
Lines 287 to 306 in 05c888b
Something like
cpp11/vignettes/FAQ.Rmd
Lines 499 to 503 in 05c888b
Be careful to avoid all the pitfalls of calling
unwind_protect()manually that are mentioned in that vignette