Skip to content

Commit 1487985

Browse files
authored
Merge pull request #7 from pachadotdev/nullable_extptr
implement #312
2 parents 66d37b1 + b1d8ecd commit 1487985

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

cpp11test/R/cpp11.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,14 @@ rcpp_push_and_truncate_ <- function(size_sxp) {
256256
.Call(`_cpp11test_rcpp_push_and_truncate_`, size_sxp)
257257
}
258258

259+
nullable_extptr_1 <- function() {
260+
.Call(`_cpp11test_nullable_extptr_1`)
261+
}
262+
263+
nullable_extptr_2 <- function() {
264+
.Call(`_cpp11test_nullable_extptr_2`)
265+
}
266+
259267
test_destruction_inner <- function() {
260268
invisible(.Call(`_cpp11test_test_destruction_inner`))
261269
}

cpp11test/src/cpp11.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,20 @@ extern "C" SEXP _cpp11test_rcpp_push_and_truncate_(SEXP size_sxp) {
478478
return cpp11::as_sexp(rcpp_push_and_truncate_(cpp11::as_cpp<cpp11::decay_t<SEXP>>(size_sxp)));
479479
END_CPP11
480480
}
481+
// test-external_pointer.cpp
482+
cpp11::external_pointer<int> nullable_extptr_1();
483+
extern "C" SEXP _cpp11test_nullable_extptr_1() {
484+
BEGIN_CPP11
485+
return cpp11::as_sexp(nullable_extptr_1());
486+
END_CPP11
487+
}
488+
// test-external_pointer.cpp
489+
cpp11::external_pointer<int> nullable_extptr_2();
490+
extern "C" SEXP _cpp11test_nullable_extptr_2() {
491+
BEGIN_CPP11
492+
return cpp11::as_sexp(nullable_extptr_2());
493+
END_CPP11
494+
}
481495
// test-protect-nested.cpp
482496
void test_destruction_inner();
483497
extern "C" SEXP _cpp11test_test_destruction_inner() {
@@ -540,6 +554,8 @@ static const R_CallMethodDef CallEntries[] = {
540554
{"_cpp11test_my_warning_n1", (DL_FUNC) &_cpp11test_my_warning_n1, 1},
541555
{"_cpp11test_my_warning_n1fmt", (DL_FUNC) &_cpp11test_my_warning_n1fmt, 1},
542556
{"_cpp11test_my_warning_n2fmt", (DL_FUNC) &_cpp11test_my_warning_n2fmt, 2},
557+
{"_cpp11test_nullable_extptr_1", (DL_FUNC) &_cpp11test_nullable_extptr_1, 0},
558+
{"_cpp11test_nullable_extptr_2", (DL_FUNC) &_cpp11test_nullable_extptr_2, 0},
543559
{"_cpp11test_protect_many_", (DL_FUNC) &_cpp11test_protect_many_, 1},
544560
{"_cpp11test_protect_many_cpp11_", (DL_FUNC) &_cpp11test_protect_many_cpp11_, 1},
545561
{"_cpp11test_protect_many_preserve_", (DL_FUNC) &_cpp11test_protect_many_preserve_, 1},

cpp11test/src/test-external_pointer.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ void deleter(int* ptr) {
1010
delete ptr;
1111
}
1212

13+
// Pacha: Test nullable external_pointer (#312)
14+
[[cpp11::register]] cpp11::external_pointer<int> nullable_extptr_1() {
15+
return cpp11::external_pointer<int>(nullptr);
16+
}
17+
18+
[[cpp11::register]] cpp11::external_pointer<int> nullable_extptr_2() {
19+
return cpp11::external_pointer<int>(R_NilValue);
20+
}
21+
1322
context("external_pointer-C++") {
1423
test_that("external_pointer works") {
1524
std::vector<int>* v = new std::vector<int>;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Pacha: test that nullable external pointer is consistent (#312)
2+
test_that("nullable external pointer is consistent", {
3+
4+
len <- 1e5
5+
set.seed(42)
6+
x <- rnorm(len)
7+
sum_base <- sum(x)
8+
9+
expect_equal(nullable_extptr_1(), NULL)
10+
expect_equal(nullable_extptr_2(), NULL)
11+
})

inst/include/cpp11/external_pointer.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ class external_pointer {
2323
sexp data_ = R_NilValue;
2424

2525
static SEXP valid_type(SEXP data) {
26-
if (data == nullptr) {
27-
throw type_error(EXTPTRSXP, NILSXP);
26+
// Pacha: Allow nullable external_pointer (#312)
27+
if (data == R_NilValue) {
28+
return data;
2829
}
2930
if (detail::r_typeof(data) != EXTPTRSXP) {
3031
throw type_error(EXTPTRSXP, detail::r_typeof(data));
@@ -120,7 +121,8 @@ class external_pointer {
120121
data_ = tmp;
121122
}
122123

123-
operator bool() noexcept { return data_ != nullptr; }
124+
// Pacha: Support nullable external_pointer (#312)
125+
operator bool() const noexcept { return data_ != R_NilValue; }
124126
};
125127

126128
template <class T, void Deleter(T*)>

0 commit comments

Comments
 (0)