Skip to content

Commit 8e7a80d

Browse files
authored
Merge pull request #5 from pachadotdev/issue297
Issue297
2 parents 7256c37 + 713f147 commit 8e7a80d

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed

cpp11test/src/test-doubles.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "cpp11/doubles.hpp"
44
#include "cpp11/function.hpp"
55
#include "cpp11/integers.hpp"
6+
#include "cpp11/logicals.hpp"
67
#include "cpp11/sexp.hpp"
78
#include "cpp11/strings.hpp"
89

@@ -454,6 +455,22 @@ context("doubles-C++") {
454455
expect_true(!cpp11::is_na(na2[1]));
455456
}
456457

458+
test_that("as_doubles(logicals)") {
459+
cpp11::writable::logicals y;
460+
461+
for (int i = 0; i < 4; i++) {
462+
y.push_back(i % 2 == 0);
463+
}
464+
465+
cpp11::doubles i(cpp11::as_doubles(y));
466+
467+
expect_true(i[0] == 1.0);
468+
expect_true(i[1] == 0.0);
469+
expect_true(i[2] == 1.0);
470+
expect_true(i[3] == 0.0);
471+
expect_true(cpp11::detail::r_typeof(i) == REALSXP);
472+
}
473+
457474
test_that("doubles operator[] and at") {
458475
cpp11::doubles x(Rf_allocVector(REALSXP, 2));
459476
REAL(x)[0] = 1;

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: 11 additions & 3 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,20 +72,27 @@ 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+
} else if (detail::r_typeof(x) == LGLSXP) {
89+
logicals xn(x);
90+
size_t len = xn.size();
91+
writable::doubles ret(len);
92+
std::transform(xn.begin(), xn.end(), ret.begin(), [](bool value) {
93+
return value == NA_LOGICAL ? NA_REAL : static_cast<double>(value);
94+
});
95+
return ret;
8896
}
8997

9098
throw type_error(REALSXP, detail::r_typeof(x));

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)