| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f764ada commit 6c34d21
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -331,8 +331,6 @@ context("as_cpp-C++") { | |||
| 331 | 331 | test_that("as_sexp(bool)") { | |
| 332 | 332 | SEXP l1 = PROTECT(cpp11::as_sexp(true)); | |
| 333 | 333 | SEXP l2 = PROTECT(cpp11::as_sexp(false)); | |
| 334 | - /* TODO: handle NA_LOGICAL, possibly need a separate enum class rather than relying | ||
| 335 | - * on bool or R's Rboolean */ | ||
| 336 | 334 | ||
| 337 | 335 | expect_true(Rf_isLogical(l1)); | |
| 338 | 336 | expect_true(Rf_xlength(l1) == 1); | |
@@ -345,6 +343,26 @@ context("as_cpp-C++") { | |||
| 345 | 343 | UNPROTECT(2); | |
| 346 | 344 | } | |
| 347 | 345 | ||
| 346 | + test_that("as_sexp(r_bool)") { | ||
| 347 | + SEXP l1 = PROTECT(cpp11::as_sexp(cpp11::r_bool(true))); | ||
| 348 | + SEXP l2 = PROTECT(cpp11::as_sexp(cpp11::r_bool(false))); | ||
| 349 | + SEXP l3 = PROTECT(cpp11::as_sexp(cpp11::r_bool())); | ||
| 350 | + | ||
| 351 | + expect_true(Rf_isLogical(l1)); | ||
| 352 | + expect_true(Rf_xlength(l1) == 1); | ||
| 353 | + expect_true(LOGICAL(l1)[0] == TRUE); | ||
| 354 | + | ||
| 355 | + expect_true(Rf_isLogical(l2)); | ||
| 356 | + expect_true(Rf_xlength(l2) == 1); | ||
| 357 | + expect_true(LOGICAL(l2)[0] == FALSE); | ||
| 358 | + | ||
| 359 | + expect_true(Rf_isLogical(l3)); | ||
| 360 | + expect_true(Rf_xlength(l3) == 1); | ||
| 361 | + expect_true(LOGICAL(l3)[0] == NA_LOGICAL); | ||
| 362 | + | ||
| 363 | + UNPROTECT(3); | ||
| 364 | + } | ||
| 365 | + | ||
| 348 | 366 | test_that("as_sexp(raws)") { | |
| 349 | 367 | cpp11::writable::raws x; | |
| 350 | 368 | x.push_back(0); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -126,11 +126,11 @@ context("logicals-C++") { | |||
| 126 | 126 | ||
| 127 | 127 | UNPROTECT(1); | |
| 128 | 128 | } | |
| 129 | - test_that("is_na(Rboolean)") { | ||
| 130 | - Rboolean x = TRUE; | ||
| 129 | + test_that("is_na(r_bool)") { | ||
| 130 | + cpp11::r_bool x = TRUE; | ||
| 131 | 131 | expect_true(!cpp11::is_na(x)); | |
| 132 | 132 | ||
| 133 | - Rboolean y = NA_LOGICAL; | ||
| 133 | + cpp11::r_bool y = NA_LOGICAL; | ||
| 134 | 134 | expect_true(cpp11::is_na(y)); | |
| 135 | 135 | } | |
| 136 | 136 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,7 @@ | |||
| 16 | 16 | #include "cpp11/matrix.hpp" | |
| 17 | 17 | #include "cpp11/named_arg.hpp" | |
| 18 | 18 | #include "cpp11/protect.hpp" | |
| 19 | + #include "cpp11/r_bool.hpp" | ||
| 19 | 20 | #include "cpp11/r_string.hpp" | |
| 20 | 21 | #include "cpp11/r_vector.hpp" | |
| 21 | 22 | #include "cpp11/raws.hpp" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,28 +1,16 @@ | |||
| 1 | 1 | #pragma once | |
| 2 | 2 | ||
| 3 | - #include <limits> | ||
| 4 | - | ||
| 5 | - #include "R_ext/Arith.h" | ||
| 6 | - | ||
| 7 | - #undef FALSE | ||
| 8 | - #undef TRUE | ||
| 9 | - #undef NA_LOGICAL | ||
| 10 | - | ||
| 11 | - extern "C" { | ||
| 12 | - typedef enum { | ||
| 13 | - FALSE = 0, | ||
| 14 | - TRUE = 1, | ||
| 15 | - NA_LOGICAL = std::numeric_limits<int>::min() | ||
| 16 | - } Rboolean; | ||
| 17 | - } | ||
| 18 | - | ||
| 19 | - #define R_EXT_BOOLEAN_H_ | ||
| 3 | + #ifdef R_INTERNALS_H_ | ||
| 4 | + #if !(defined(R_NO_REMAP) && defined(STRICT_R_HEADERS)) | ||
| 5 | + #error R headers were included before cpp11 headers \ | ||
| 6 | + and at least one of R_NO_REMAP or STRICT_R_HEADERS \ | ||
| 7 | + was not defined. | ||
| 8 | + #endif | ||
| 9 | + #endif | ||
| 20 | 10 | ||
| 21 | 11 | #define R_NO_REMAP | |
| 22 | 12 | #define STRICT_R_HEADERS | |
| 23 | 13 | #include "Rinternals.h" | |
| 24 | - #undef STRICT_R_HEADERS | ||
| 25 | - #undef R_NO_REMAP | ||
| 26 | 14 | ||
| 27 | 15 | // clang-format off | |
| 28 | 16 | #ifdef __clang__ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | 7 | #include "cpp11/R.hpp" // for SEXP, SEXPREC, TYPEOF, R_NilValue, R_C... | |
| 8 | 8 | #include "cpp11/protect.hpp" // for protect, safe, protect::function | |
| 9 | + #include "cpp11/r_bool.hpp" // for r_bool | ||
| 9 | 10 | #include "cpp11/r_vector.hpp" // for type_error | |
| 10 | 11 | #include "cpp11/sexp.hpp" // for sexp | |
| 11 | 12 | ||
@@ -54,7 +55,7 @@ class external_pointer { | |||
| 54 | 55 | external_pointer(pointer p, bool use_deleter = true, bool finalize_on_exit = true) | |
| 55 | 56 | : data_(safe[R_MakeExternalPtr]((void*)p, R_NilValue, R_NilValue)) { | |
| 56 | 57 | if (use_deleter) { | |
| 57 | - R_RegisterCFinalizerEx(data_, r_deleter, static_cast<Rboolean>(finalize_on_exit)); | ||
| 58 | + R_RegisterCFinalizerEx(data_, r_deleter, static_cast<r_bool>(finalize_on_exit)); | ||
| 58 | 59 | } | |
| 59 | 60 | } | |
| 60 | 61 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,10 +4,11 @@ | |||
| 4 | 4 | #include <array> // for array | |
| 5 | 5 | #include <initializer_list> // for initializer_list | |
| 6 | 6 | ||
| 7 | - #include "cpp11/R.hpp" // for Rboolean, SEXP, SEXPREC, Rf_all... | ||
| 7 | + #include "cpp11/R.hpp" // for SEXP, SEXPREC, Rf_all... | ||
| 8 | 8 | #include "cpp11/attribute_proxy.hpp" // for attribute_proxy | |
| 9 | 9 | #include "cpp11/named_arg.hpp" // for named_arg | |
| 10 | 10 | #include "cpp11/protect.hpp" // for preserved | |
| 11 | + #include "cpp11/r_bool.hpp" // for r_bool | ||
| 11 | 12 | #include "cpp11/r_vector.hpp" // for r_vector, r_vector<>::proxy | |
| 12 | 13 | #include "cpp11/sexp.hpp" // for sexp | |
| 13 | 14 | ||
@@ -16,41 +17,41 @@ | |||
| 16 | 17 | namespace cpp11 { | |
| 17 | 18 | ||
| 18 | 19 | template <> | |
| 19 | - inline SEXP r_vector<Rboolean>::valid_type(SEXP data) { | ||
| 20 | + inline SEXP r_vector<r_bool>::valid_type(SEXP data) { | ||
| 20 | 21 | if (TYPEOF(data) != LGLSXP) { | |
| 21 | 22 | throw type_error(LGLSXP, TYPEOF(data)); | |
| 22 | 23 | } | |
| 23 | 24 | return data; | |
| 24 | 25 | } | |
| 25 | 26 | ||
| 26 | 27 | template <> | |
| 27 | - inline Rboolean r_vector<Rboolean>::operator[](const R_xlen_t pos) const { | ||
| 28 | - return is_altrep_ ? static_cast<Rboolean>(LOGICAL_ELT(data_, pos)) : data_p_[pos]; | ||
| 28 | + inline r_bool r_vector<r_bool>::operator[](const R_xlen_t pos) const { | ||
| 29 | + return is_altrep_ ? static_cast<r_bool>(LOGICAL_ELT(data_, pos)) : data_p_[pos]; | ||
| 29 | 30 | } | |
| 30 | 31 | ||
| 31 | 32 | template <> | |
| 32 | - inline Rboolean* r_vector<Rboolean>::get_p(bool is_altrep, SEXP data) { | ||
| 33 | + inline r_bool* r_vector<r_bool>::get_p(bool is_altrep, SEXP data) { | ||
| 33 | 34 | if (is_altrep) { | |
| 34 | 35 | return nullptr; | |
| 35 | 36 | } else { | |
| 36 | - return reinterpret_cast<Rboolean*>(LOGICAL(data)); | ||
| 37 | + return reinterpret_cast<r_bool*>(LOGICAL(data)); | ||
| 37 | 38 | } | |
| 38 | 39 | } | |
| 39 | 40 | ||
| 40 | 41 | template <> | |
| 41 | - inline void r_vector<Rboolean>::const_iterator::fill_buf(R_xlen_t pos) { | ||
| 42 | + inline void r_vector<r_bool>::const_iterator::fill_buf(R_xlen_t pos) { | ||
| 42 | 43 | length_ = std::min(64_xl, data_->size() - pos); | |
| 43 | 44 | LOGICAL_GET_REGION(data_->data_, pos, length_, reinterpret_cast<int*>(buf_.data())); | |
| 44 | 45 | block_start_ = pos; | |
| 45 | 46 | } | |
| 46 | 47 | ||
| 47 | - typedef r_vector<Rboolean> logicals; | ||
| 48 | + typedef r_vector<r_bool> logicals; | ||
| 48 | 49 | ||
| 49 | 50 | namespace writable { | |
| 50 | 51 | ||
| 51 | 52 | template <> | |
| 52 | - inline typename r_vector<Rboolean>::proxy& r_vector<Rboolean>::proxy::operator=( | ||
| 53 | - const Rboolean& rhs) { | ||
| 53 | + inline typename r_vector<r_bool>::proxy& r_vector<r_bool>::proxy::operator=( | ||
| 54 | + const r_bool& rhs) { | ||
| 54 | 55 | if (is_altrep_) { | |
| 55 | 56 | SET_LOGICAL_ELT(data_, index_, rhs); | |
| 56 | 57 | } else { | |
@@ -60,17 +61,21 @@ inline typename r_vector<Rboolean>::proxy& r_vector<Rboolean>::proxy::operator=( | |||
| 60 | 61 | } | |
| 61 | 62 | ||
| 62 | 63 | template <> | |
| 63 | - inline r_vector<Rboolean>::proxy::operator Rboolean() const { | ||
| 64 | + inline r_vector<r_bool>::proxy::operator r_bool() const { | ||
| 64 | 65 | if (p_ == nullptr) { | |
| 65 | - return static_cast<Rboolean>(LOGICAL_ELT(data_, index_)); | ||
| 66 | + return static_cast<r_bool>(LOGICAL_ELT(data_, index_)); | ||
| 66 | 67 | } else { | |
| 67 | 68 | return *p_; | |
| 68 | 69 | } | |
| 69 | 70 | } | |
| 70 | 71 | ||
| 72 | + inline bool operator==(const r_vector<r_bool>::proxy& lhs, r_bool rhs) { | ||
| 73 | + return static_cast<r_bool>(lhs).operator==(rhs); | ||
| 74 | + } | ||
| 75 | + | ||
| 71 | 76 | template <> | |
| 72 | - inline r_vector<Rboolean>::r_vector(std::initializer_list<Rboolean> il) | ||
| 73 | - : cpp11::r_vector<Rboolean>(Rf_allocVector(LGLSXP, il.size())), capacity_(il.size()) { | ||
| 77 | + inline r_vector<r_bool>::r_vector(std::initializer_list<r_bool> il) | ||
| 78 | + : cpp11::r_vector<r_bool>(Rf_allocVector(LGLSXP, il.size())), capacity_(il.size()) { | ||
| 74 | 79 | protect_ = preserved.insert(data_); | |
| 75 | 80 | auto it = il.begin(); | |
| 76 | 81 | for (R_xlen_t i = 0; i < capacity_; ++i, ++it) { | |
@@ -79,8 +84,8 @@ inline r_vector<Rboolean>::r_vector(std::initializer_list<Rboolean> il) | |||
| 79 | 84 | } | |
| 80 | 85 | ||
| 81 | 86 | template <> | |
| 82 | - inline r_vector<Rboolean>::r_vector(std::initializer_list<named_arg> il) | ||
| 83 | - : cpp11::r_vector<Rboolean>(safe[Rf_allocVector](LGLSXP, il.size())), | ||
| 87 | + inline r_vector<r_bool>::r_vector(std::initializer_list<named_arg> il) | ||
| 88 | + : cpp11::r_vector<r_bool>(safe[Rf_allocVector](LGLSXP, il.size())), | ||
| 84 | 89 | capacity_(il.size()) { | |
| 85 | 90 | protect_ = preserved.insert(data_); | |
| 86 | 91 | int n_protected = 0; | |
@@ -92,7 +97,7 @@ inline r_vector<Rboolean>::r_vector(std::initializer_list<named_arg> il) | |||
| 92 | 97 | ++n_protected; | |
| 93 | 98 | auto it = il.begin(); | |
| 94 | 99 | for (R_xlen_t i = 0; i < capacity_; ++i, ++it) { | |
| 95 | - data_p_[i] = static_cast<Rboolean>(LOGICAL_ELT(it->value(), 0)); | ||
| 100 | + data_p_[i] = static_cast<r_bool>(LOGICAL_ELT(it->value(), 0)); | ||
| 96 | 101 | SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8)); | |
| 97 | 102 | } | |
| 98 | 103 | UNPROTECT(n_protected); | |
@@ -105,20 +110,20 @@ inline r_vector<Rboolean>::r_vector(std::initializer_list<named_arg> il) | |||
| 105 | 110 | } | |
| 106 | 111 | ||
| 107 | 112 | template <> | |
| 108 | - inline void r_vector<Rboolean>::reserve(R_xlen_t new_capacity) { | ||
| 113 | + inline void r_vector<r_bool>::reserve(R_xlen_t new_capacity) { | ||
| 109 | 114 | data_ = data_ == R_NilValue ? safe[Rf_allocVector](LGLSXP, new_capacity) | |
| 110 | 115 | : safe[Rf_xlengthgets](data_, new_capacity); | |
| 111 | 116 | SEXP old_protect = protect_; | |
| 112 | 117 | protect_ = preserved.insert(data_); | |
| 113 | 118 | ||
| 114 | 119 | preserved.release(old_protect); | |
| 115 | 120 | ||
| 116 | - data_p_ = reinterpret_cast<Rboolean*>(LOGICAL(data_)); | ||
| 121 | + data_p_ = reinterpret_cast<r_bool*>(LOGICAL(data_)); | ||
| 117 | 122 | capacity_ = new_capacity; | |
| 118 | 123 | } | |
| 119 | 124 | ||
| 120 | 125 | template <> | |
| 121 | - inline void r_vector<Rboolean>::push_back(Rboolean value) { | ||
| 126 | + inline void r_vector<r_bool>::push_back(r_bool value) { | ||
| 122 | 127 | while (length_ >= capacity_) { | |
| 123 | 128 | reserve(capacity_ == 0 ? 1 : capacity_ *= 2); | |
| 124 | 129 | } | |
@@ -130,9 +135,7 @@ inline void r_vector<Rboolean>::push_back(Rboolean value) { | |||
| 130 | 135 | ++length_; | |
| 131 | 136 | } | |
| 132 | 137 | ||
| 133 | - typedef r_vector<Rboolean> logicals; | ||
| 138 | + typedef r_vector<r_bool> logicals; | ||
| 134 | 139 | ||
| 135 | 140 | } // namespace writable | |
| 136 | - | ||
| 137 | - inline bool is_na(Rboolean x) { return x == NA_LOGICAL; } | ||
| 138 | 141 | } // namespace cpp11 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,7 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | 3 | #include <string> // for string | |
| 4 | 4 | ||
| 5 | - #include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, Rboolean, INT... | ||
| 5 | + #include "cpp11/R.hpp" // for SEXP, SEXPREC, R_xlen_t, INT... | ||
| 6 | + #include "cpp11/r_bool.hpp" // for r_bool | ||
| 6 | 7 | #include "cpp11/r_string.hpp" // for r_string | |
| 7 | 8 | #include "cpp11/r_vector.hpp" // for r_vector | |
| 8 | 9 | #include "cpp11/sexp.hpp" // for sexp | |
@@ -95,13 +96,13 @@ class matrix { | |||
| 95 | 96 | ||
| 96 | 97 | using doubles_matrix = matrix<r_vector<double>, double>; | |
| 97 | 98 | using integers_matrix = matrix<r_vector<int>, int>; | |
| 98 | - using logicals_matrix = matrix<r_vector<Rboolean>, Rboolean>; | ||
| 99 | + using logicals_matrix = matrix<r_vector<r_bool>, r_bool>; | ||
| 99 | 100 | using strings_matrix = matrix<r_vector<r_string>, r_string>; | |
| 100 | 101 | ||
| 101 | 102 | namespace writable { | |
| 102 | 103 | using doubles_matrix = matrix<r_vector<double>, r_vector<double>::proxy>; | |
| 103 | 104 | using integers_matrix = matrix<r_vector<int>, r_vector<int>::proxy>; | |
| 104 | - using logicals_matrix = matrix<r_vector<Rboolean>, r_vector<Rboolean>::proxy>; | ||
| 105 | + using logicals_matrix = matrix<r_vector<r_bool>, r_vector<r_bool>::proxy>; | ||
| 105 | 106 | using strings_matrix = matrix<r_vector<r_string>, r_vector<r_string>::proxy>; | |
| 106 | 107 | } // namespace writable | |
| 107 | 108 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,13 +6,14 @@ | |||
| 6 | 6 | #include <string> // for string, basic_string | |
| 7 | 7 | #include <tuple> // for tuple, make_tuple | |
| 8 | 8 | ||
| 9 | - // NB: cpp11/R.hpp must precede R_ext includes so our definition of Rboolean is used | ||
| 9 | + // NB: cpp11/R.hpp must precede R_ext/Error.h to ensure R_NO_REMAP is defined | ||
| 10 | 10 | #include "cpp11/R.hpp" // for SEXP, SEXPREC, CDR, R_NilValue, CAR, R_Pres... | |
| 11 | 11 | ||
| 12 | - #include "R_ext/Error.h" // for Rf_error, Rf_warning | ||
| 13 | - #include "R_ext/Print.h" // for REprintf | ||
| 14 | - #include "R_ext/Utils.h" // for R_CheckUserInterrupt | ||
| 15 | - #include "Rversion.h" // for R_VERSION, R_Version | ||
| 12 | + #include "R_ext/Boolean.h" // for Rboolean | ||
| 13 | + #include "R_ext/Error.h" // for Rf_error, Rf_warning | ||
| 14 | + #include "R_ext/Print.h" // for REprintf | ||
| 15 | + #include "R_ext/Utils.h" // for R_CheckUserInterrupt | ||
| 16 | + #include "Rversion.h" // for R_VERSION, R_Version | ||
| 16 | 17 | ||
| 17 | 18 | #if defined(R_VERSION) && R_VERSION >= R_Version(3, 5, 0) | |
| 18 | 19 | #define HAS_UNWIND_PROTECT | |
@@ -51,7 +52,7 @@ SEXP unwind_protect(Fun&& code) { | |||
| 51 | 52 | }, | |
| 52 | 53 | &code, | |
| 53 | 54 | [](void* jmpbuf, Rboolean jump) { | |
| 54 | - if (jump) { | ||
| 55 | + if (jump == TRUE) { | ||
| 55 | 56 | // We need to first jump back into the C++ stacks because you can't safely throw | |
| 56 | 57 | // exceptions from C stack frames. | |
| 57 | 58 | longjmp(*static_cast<std::jmp_buf*>(jmpbuf), 1); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,64 @@ | |||
| 1 | + #pragma once | ||
| 2 | + | ||
| 3 | + #include <limits> // for numeric_limits | ||
| 4 | + #include <type_traits> // for is_convertible, enable_if | ||
| 5 | + | ||
| 6 | + #include "R_ext/Boolean.h" // for Rboolean | ||
| 7 | + #include "cpp11/R.hpp" // for SEXP, SEXPREC, ... | ||
| 8 | + #include "cpp11/as.hpp" // for as_sexp | ||
| 9 | + #include "cpp11/protect.hpp" // for unwind_protect, preserved | ||
| 10 | + #include "cpp11/sexp.hpp" // for sexp | ||
| 11 | + | ||
| 12 | + namespace cpp11 { | ||
| 13 | + | ||
| 14 | + class r_bool { | ||
| 15 | + public: | ||
| 16 | + r_bool() = default; | ||
| 17 | + | ||
| 18 | + r_bool(SEXP data) { | ||
| 19 | + if (Rf_isLogical(data)) { | ||
| 20 | + if (Rf_xlength(data) == 1) { | ||
| 21 | + value_ = static_cast<Rboolean>(LOGICAL_ELT(data, 0)); | ||
| 22 | + } | ||
| 23 | + } | ||
| 24 | + stop("Invalid r_bool value: %x", data); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + r_bool(bool value) : value_(value ? TRUE : FALSE) {} | ||
| 28 | + r_bool(Rboolean value) : value_(value) {} | ||
| 29 | + r_bool(int value) : value_(from_int(value)) {} | ||
| 30 | + | ||
| 31 | + explicit operator bool() const { return value_ == TRUE; } | ||
| 32 | + operator int() const { return value_; } | ||
| 33 | + operator Rboolean() const { return value_; } | ||
| 34 | + | ||
| 35 | + bool operator==(r_bool rhs) const { return value_ == rhs.value_; } | ||
| 36 | + bool operator==(bool rhs) const { return operator==(r_bool(rhs)); } | ||
| 37 | + bool operator==(Rboolean rhs) const { return operator==(r_bool(rhs)); } | ||
| 38 | + bool operator==(int rhs) const { return operator==(r_bool(rhs)); } | ||
| 39 | + | ||
| 40 | + private: | ||
| 41 | + static constexpr Rboolean na = static_cast<Rboolean>(std::numeric_limits<int>::min()); | ||
| 42 | + | ||
| 43 | + static Rboolean from_int(int value) { | ||
| 44 | + if (value == static_cast<int>(FALSE)) return FALSE; | ||
| 45 | + if (value == static_cast<int>(na)) return na; | ||
| 46 | + return TRUE; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + Rboolean value_ = na; | ||
| 50 | + }; | ||
| 51 | + | ||
| 52 | + inline bool is_na(r_bool x) { return x == r_bool(); } | ||
| 53 | + | ||
| 54 | + template <typename T, typename R = void> | ||
| 55 | + using enable_if_r_bool = enable_if_t<std::is_same<T, r_bool>::value, R>; | ||
| 56 | + | ||
| 57 | + template <typename T> | ||
| 58 | + enable_if_r_bool<T, SEXP> as_sexp(T from) { | ||
| 59 | + sexp res = Rf_allocVector(LGLSXP, 1); | ||
| 60 | + safe[SET_LOGICAL_ELT](res.data(), 0, static_cast<Rboolean>(from)); | ||
| 61 | + return res; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + } // namespace cpp11 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments