Skip to content

Commit

Permalink
Refactor conversion to use extensible trait structs
Browse files Browse the repository at this point in the history
  • Loading branch information
bkietz committed Sep 17, 2020
1 parent bb6745f commit 7fe7d57
Show file tree
Hide file tree
Showing 4 changed files with 365 additions and 249 deletions.
44 changes: 44 additions & 0 deletions cpp11test/src/test-as.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@

#include "Rcpp.h"

struct Vec3 {
double x, y, z;
};

namespace cpp11 {
template <>
struct as_cpp_impl<Vec3> {
static Vec3 convert(SEXP from) {
if (Rf_isReal(from)) {
if (Rf_xlength(from) == 3) {
return {REAL_ELT(from, 0), REAL_ELT(from, 1), REAL_ELT(from, 2)};
}
}
stop("Expected three double values");
}
};
} // namespace cpp11

context("as_cpp-C++") {
test_that("as_cpp<integer>(INTSEXP)") {
SEXP r = PROTECT(Rf_allocVector(INTSXP, 1));
Expand Down Expand Up @@ -57,6 +75,18 @@ context("as_cpp-C++") {
UNPROTECT(1);
}

test_that("as_cpp<Vec3>(REALSXP)") {
SEXP r = PROTECT(Rf_allocVector(REALSXP, 3));
REAL(r)[0] = 1;
REAL(r)[1] = 2;
REAL(r)[2] = 4;

Vec3 v = cpp11::as_cpp<Vec3>(r);
expect_true(v.x == 1);
expect_true(v.y == 2);
expect_true(v.z == 4);
}

test_that("as_cpp<integer>(NA)") {
SEXP r = PROTECT(Rf_allocVector(REALSXP, 1));
SEXP i = PROTECT(Rf_allocVector(INTSXP, 1));
Expand Down Expand Up @@ -209,6 +239,20 @@ context("as_cpp-C++") {
UNPROTECT(1);
}

test_that("as_cpp<std::vector>(ALTREP_INTSXP)") {
SEXP r = PROTECT(R_compact_intrange(1, 5));

auto x1 = cpp11::as_cpp<std::vector<int>>(r);
expect_true(x1.size() == 5);
expect_true(x1[0] == 1);
expect_true(x1[1] == 2);
expect_true(x1[2] == 3);
expect_true(x1[3] == 4);
expect_true(x1[5] == 5);

UNPROTECT(1);
}

test_that("as_cpp<std::vector<std::string>>()") {
SEXP r = PROTECT(Rf_allocVector(STRSXP, 3));
SET_STRING_ELT(r, 0, Rf_mkChar("foo"));
Expand Down
Loading

0 comments on commit 7fe7d57

Please sign in to comment.