diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/arrow/r/inst/include/cpp11/r_bool.hpp | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/arrow/r/inst/include/cpp11/r_bool.hpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/arrow/r/inst/include/cpp11/r_bool.hpp b/src/arrow/r/inst/include/cpp11/r_bool.hpp new file mode 100644 index 000000000..e5c8592d7 --- /dev/null +++ b/src/arrow/r/inst/include/cpp11/r_bool.hpp @@ -0,0 +1,76 @@ +// cpp11 version: 0.3.1.1 +// vendored on: 2021-08-11 +#pragma once + +#include <limits> // for numeric_limits +#include <ostream> +#include <type_traits> // for is_convertible, enable_if + +#include "R_ext/Boolean.h" // for Rboolean +#include "cpp11/R.hpp" // for SEXP, SEXPREC, ... +#include "cpp11/as.hpp" // for as_sexp +#include "cpp11/protect.hpp" // for unwind_protect, preserved +#include "cpp11/r_vector.hpp" +#include "cpp11/sexp.hpp" // for sexp + +namespace cpp11 { + +class r_bool { + public: + r_bool() = default; + + r_bool(SEXP data) { + if (Rf_isLogical(data)) { + if (Rf_xlength(data) == 1) { + value_ = static_cast<Rboolean>(LOGICAL_ELT(data, 0)); + } + } + stop("Invalid r_bool value: %x", data); + } + + r_bool(bool value) : value_(value ? TRUE : FALSE) {} + r_bool(Rboolean value) : value_(value) {} + r_bool(int value) : value_(from_int(value)) {} + + operator bool() const { return value_ == TRUE; } + operator int() const { return value_; } + operator Rboolean() const { return value_ ? TRUE : FALSE; } + + bool operator==(r_bool rhs) const { return value_ == rhs.value_; } + bool operator==(bool rhs) const { return operator==(r_bool(rhs)); } + bool operator==(Rboolean rhs) const { return operator==(r_bool(rhs)); } + bool operator==(int rhs) const { return operator==(r_bool(rhs)); } + + private: + static constexpr int na = std::numeric_limits<int>::min(); + + static int from_int(int value) { + if (value == static_cast<int>(FALSE)) return FALSE; + if (value == static_cast<int>(na)) return na; + return TRUE; + } + + int value_ = na; +}; + +inline std::ostream& operator<<(std::ostream& os, r_bool const& value) { + os << ((value == TRUE) ? "TRUE" : "FALSE"); + return os; +} + +template <typename T, typename R = void> +using enable_if_r_bool = enable_if_t<std::is_same<T, r_bool>::value, R>; + +template <typename T> +enable_if_r_bool<T, SEXP> as_sexp(T from) { + sexp res = Rf_allocVector(LGLSXP, 1); + unwind_protect([&] { SET_LOGICAL_ELT(res.data(), 0, from); }); + return res; +} + +template <> +inline r_bool na() { + return NA_LOGICAL; +} + +} // namespace cpp11 |