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().
| SEXPas_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