1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#pragma once
#include <stddef.h> // for size_t
#include <string> // for string, basic_string
#include "cpp11/R.hpp" // for SEXP, SEXPREC, REAL_ELT, R_NilV...
#include "cpp11/attribute_proxy.hpp" // for attribute_proxy
#include "cpp11/protect.hpp" // for store
namespace cpp11 {
/// Converting to SEXP
class sexp {
private:
SEXP data_ = R_NilValue;
SEXP preserve_token_ = R_NilValue;
public:
sexp() = default;
sexp(SEXP data) : data_(data), preserve_token_(detail::store::insert(data_)) {}
// We maintain our own new `preserve_token_`
sexp(const sexp& rhs) {
data_ = rhs.data_;
preserve_token_ = detail::store::insert(data_);
}
// We take ownership over the `rhs.preserve_token_`.
// Importantly we clear it in the `rhs` so it can't release the object upon destruction.
sexp(sexp&& rhs) {
data_ = rhs.data_;
preserve_token_ = rhs.preserve_token_;
rhs.data_ = R_NilValue;
rhs.preserve_token_ = R_NilValue;
}
sexp& operator=(const sexp& rhs) {
detail::store::release(preserve_token_);
data_ = rhs.data_;
preserve_token_ = detail::store::insert(data_);
return *this;
}
~sexp() { detail::store::release(preserve_token_); }
attribute_proxy<sexp> attr(const char* name) const {
return attribute_proxy<sexp>(*this, name);
}
attribute_proxy<sexp> attr(const std::string& name) const {
return attribute_proxy<sexp>(*this, name.c_str());
}
attribute_proxy<sexp> attr(SEXP name) const {
return attribute_proxy<sexp>(*this, name);
}
attribute_proxy<sexp> names() const {
return attribute_proxy<sexp>(*this, R_NamesSymbol);
}
operator SEXP() const { return data_; }
SEXP data() const { return data_; }
/// DEPRECATED: Do not use this, it will be removed soon.
operator double() const { return REAL_ELT(data_, 0); }
/// DEPRECATED: Do not use this, it will be removed soon.
operator size_t() const { return REAL_ELT(data_, 0); }
/// DEPRECATED: Do not use this, it will be removed soon.
operator bool() const { return LOGICAL_ELT(data_, 0); }
};
} // namespace cpp11
|