Skip to content

Commit 713f147

Browse files
committed
bool -> int + using transform for bool -> double
1 parent f5d6054 commit 713f147

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

cpp11test/src/test-integers.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "cpp11/doubles.hpp"
33
#include "cpp11/function.hpp"
44
#include "cpp11/integers.hpp"
5+
#include "cpp11/logicals.hpp"
56
#include "cpp11/strings.hpp"
67

78
#include <testthat.h>
@@ -43,6 +44,22 @@ context("integers-C++") {
4344
expect_true(!cpp11::is_na(na2[1]));
4445
}
4546

47+
test_that("as_integers(logicals)") {
48+
cpp11::writable::logicals y;
49+
50+
for (int i = 0; i < 4; i++) {
51+
y.push_back(i % 2 == 0);
52+
}
53+
54+
cpp11::integers i(cpp11::as_integers(y));
55+
56+
expect_true(i[0] == 1);
57+
expect_true(i[1] == 0);
58+
expect_true(i[2] == 1);
59+
expect_true(i[3] == 0);
60+
expect_true(cpp11::detail::r_typeof(i) == INTSXP);
61+
}
62+
4663
test_that("integers.push_back()") {
4764
cpp11::writable::integers x;
4865
x.push_back(1);

inst/include/cpp11/doubles.hpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "cpp11/R.hpp" // for SEXP, SEXPREC, Rf_allocVector, REAL
99
#include "cpp11/as.hpp" // for as_sexp
1010
#include "cpp11/protect.hpp" // for safe
11+
#include "cpp11/r_bool.hpp" // for r_bool
1112
#include "cpp11/r_vector.hpp" // for vector, vector<>::proxy, vector<>::...
1213
#include "cpp11/sexp.hpp" // for sexp
1314

@@ -71,28 +72,26 @@ typedef r_vector<double> doubles;
7172
} // namespace writable
7273

7374
typedef r_vector<int> integers;
75+
typedef r_vector<r_bool> logicals;
7476

7577
inline doubles as_doubles(SEXP x) {
7678
if (detail::r_typeof(x) == REALSXP) {
7779
return doubles(x);
78-
}
79-
80-
else if (detail::r_typeof(x) == INTSXP) {
80+
} else if (detail::r_typeof(x) == INTSXP) {
8181
integers xn(x);
8282
size_t len = xn.size();
8383
writable::doubles ret(len);
8484
std::transform(xn.begin(), xn.end(), ret.begin(), [](int value) {
8585
return value == NA_INTEGER ? NA_REAL : static_cast<double>(value);
8686
});
8787
return ret;
88-
}
89-
90-
else if (detail::r_typeof(x) == LGLSXP) {
91-
size_t len = Rf_xlength(x);
88+
} else if (detail::r_typeof(x) == LGLSXP) {
89+
logicals xn(x);
90+
size_t len = xn.size();
9291
writable::doubles ret(len);
93-
for (size_t i = 0; i < len; ++i) {
94-
ret[i] = LOGICAL(x)[i] == NA_LOGICAL ? NA_REAL : static_cast<double>(LOGICAL(x)[i]);
95-
}
92+
std::transform(xn.begin(), xn.end(), ret.begin(), [](bool value) {
93+
return value == NA_LOGICAL ? NA_REAL : static_cast<double>(value);
94+
});
9695
return ret;
9796
}
9897

inst/include/cpp11/integers.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "cpp11/as.hpp" // for as_sexp
1010
#include "cpp11/attribute_proxy.hpp" // for attribute_proxy
1111
#include "cpp11/protect.hpp" // for safe
12+
#include "cpp11/r_bool.hpp" // for r_bool
1213
#include "cpp11/r_vector.hpp" // for r_vector, r_vector<>::proxy
1314
#include "cpp11/sexp.hpp" // for sexp
1415

@@ -79,6 +80,7 @@ inline int na() {
7980
// forward declaration
8081

8182
typedef r_vector<double> doubles;
83+
typedef r_vector<r_bool> logicals;
8284

8385
inline integers as_integers(SEXP x) {
8486
if (detail::r_typeof(x) == INTSXP) {
@@ -96,6 +98,14 @@ inline integers as_integers(SEXP x) {
9698
return static_cast<int>(value);
9799
});
98100
return ret;
101+
} else if (detail::r_typeof(x) == LGLSXP) {
102+
logicals xn(x);
103+
size_t len = xn.size();
104+
writable::integers ret(len);
105+
std::transform(xn.begin(), xn.end(), ret.begin(), [](bool value) {
106+
return value == NA_LOGICAL ? NA_INTEGER : static_cast<int>(value);
107+
});
108+
return ret;
99109
}
100110

101111
throw type_error(INTSXP, detail::r_typeof(x));

0 commit comments

Comments
 (0)