summaryrefslogtreecommitdiffstats
path: root/src/arrow/r/inst/include/cpp11/r_string.hpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/arrow/r/inst/include/cpp11/r_string.hpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/arrow/r/inst/include/cpp11/r_string.hpp b/src/arrow/r/inst/include/cpp11/r_string.hpp
new file mode 100644
index 000000000..d62f7270f
--- /dev/null
+++ b/src/arrow/r/inst/include/cpp11/r_string.hpp
@@ -0,0 +1,98 @@
+// cpp11 version: 0.3.1.1
+// vendored on: 2021-08-11
+#pragma once
+
+#include <string> // for string, basic_string, operator==
+#include <type_traits> // for is_convertible, enable_if
+
+#include "R_ext/Memory.h" // for vmaxget, vmaxset
+#include "cpp11/R.hpp" // for SEXP, SEXPREC, Rf_mkCharCE, Rf_translat...
+#include "cpp11/as.hpp" // for as_sexp
+#include "cpp11/protect.hpp" // for unwind_protect, protect, protect::function
+#include "cpp11/sexp.hpp" // for sexp
+
+namespace cpp11 {
+
+class r_string {
+ public:
+ r_string() = default;
+ r_string(SEXP data) : data_(data) {}
+ r_string(const char* data) : data_(safe[Rf_mkCharCE](data, CE_UTF8)) {}
+ r_string(const std::string& data)
+ : data_(safe[Rf_mkCharLenCE](data.c_str(), data.size(), CE_UTF8)) {}
+
+ operator SEXP() const { return data_; }
+ operator sexp() const { return data_; }
+ operator std::string() const {
+ std::string res;
+ res.reserve(size());
+
+ void* vmax = vmaxget();
+ unwind_protect([&] { res.assign(Rf_translateCharUTF8(data_)); });
+ vmaxset(vmax);
+
+ return res;
+ }
+
+ bool operator==(const r_string& rhs) const { return data_.data() == rhs.data_.data(); }
+
+ bool operator==(const SEXP rhs) const { return data_.data() == rhs; }
+
+ bool operator==(const char* rhs) const {
+ return static_cast<std::string>(*this) == rhs;
+ }
+
+ bool operator==(const std::string& rhs) const {
+ return static_cast<std::string>(*this) == rhs;
+ }
+
+ R_xlen_t size() const { return Rf_xlength(data_); }
+
+ private:
+ sexp data_ = R_NilValue;
+};
+
+inline SEXP as_sexp(std::initializer_list<r_string> il) {
+ R_xlen_t size = il.size();
+
+ sexp data;
+ unwind_protect([&] {
+ data = Rf_allocVector(STRSXP, size);
+ auto it = il.begin();
+ for (R_xlen_t i = 0; i < size; ++i, ++it) {
+ if (*it == NA_STRING) {
+ SET_STRING_ELT(data, i, *it);
+ } else {
+ SET_STRING_ELT(data, i, Rf_mkCharCE(Rf_translateCharUTF8(*it), CE_UTF8));
+ }
+ }
+ });
+ return data;
+}
+
+template <typename T, typename R = void>
+using enable_if_r_string = enable_if_t<std::is_same<T, cpp11::r_string>::value, R>;
+
+template <typename T>
+enable_if_r_string<T, SEXP> as_sexp(T from) {
+ r_string str(from);
+ sexp res;
+ unwind_protect([&] {
+ res = Rf_allocVector(STRSXP, 1);
+
+ if (str == NA_STRING) {
+ SET_STRING_ELT(res, 0, str);
+ } else {
+ SET_STRING_ELT(res, 0, Rf_mkCharCE(Rf_translateCharUTF8(str), CE_UTF8));
+ }
+ });
+
+ return res;
+}
+
+template <>
+inline r_string na() {
+ return NA_STRING;
+}
+
+} // namespace cpp11