Skip to content

Commit 4f2ffae

Browse files
authored
Add the Dataptr* methods to ALTREP representation (#286)
* Add the Dataptr* methods to ALTREP representation (sometimes called inside `mclapply()`) * Add tests for DATAPTR * Throw an error on s2_altrep_Dataptr(writable = true), improve tests
1 parent a344cc0 commit 4f2ffae

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/s2-altrep.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ static SEXP s2_altrep_Elt(SEXP obj, R_xlen_t i) {
2222
return VECTOR_ELT(data, i);
2323
}
2424

25+
static void s2_altrep_SetElt(SEXP obj, R_xlen_t i, SEXP v) {
26+
SEXP data = R_altrep_data1(obj);
27+
SET_VECTOR_ELT(data, i, v);
28+
}
29+
30+
static void* s2_altrep_Dataptr(SEXP obj, Rboolean writable) {
31+
if (writable) Rf_error("unable to produce writable DATAPTR for list data");
32+
33+
SEXP data = R_altrep_data1(obj);
34+
return (void*) DATAPTR_RO(data);
35+
}
36+
37+
static const void* s2_altrep_Dataptr_or_null(SEXP obj) {
38+
return s2_altrep_Dataptr(obj, FALSE);
39+
}
40+
2541
static SEXP s2_altrep_Serialized_state(SEXP obj) {
2642
// fetch the pointer to s2::s2_geography_serialize()
2743
SEXP fn = Rf_findFun(Rf_install("s2_geography_serialize"), s2_ns_pkg);
@@ -61,6 +77,9 @@ void s2_init_altrep(DllInfo *dll) {
6177

6278
R_set_altrep_Length_method(s2_geography_altrep_cls, s2_altrep_Length);
6379
R_set_altlist_Elt_method(s2_geography_altrep_cls, s2_altrep_Elt);
80+
R_set_altlist_Set_elt_method(s2_geography_altrep_cls, s2_altrep_SetElt);
81+
R_set_altvec_Dataptr_method(s2_geography_altrep_cls, s2_altrep_Dataptr);
82+
R_set_altvec_Dataptr_or_null_method(s2_geography_altrep_cls, s2_altrep_Dataptr_or_null);
6483
R_set_altrep_Serialized_state_method(s2_geography_altrep_cls, s2_altrep_Serialized_state);
6584
R_set_altrep_Unserialize_method(s2_geography_altrep_cls, s2_altrep_Unserialize);
6685
#endif

tests/testthat/test-s2-geography.R

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,18 @@ test_that("wk crs and geodesic methods are defined", {
275275

276276
expect_error(wk::wk_set_geodesic(geog, FALSE), "Can't set geodesic")
277277
})
278+
279+
test_that("s2_geography vectors support elementwise assignment", {
280+
x <- as_s2_geography(c("POINT (0 0)", "POINT (90 0)"))
281+
x[2] <- as_s2_geography(c("POINT (45 45)"))
282+
283+
expect_wkt_equal(x, c("POINT (0 0)", "POINT (45 45)"))
284+
})
285+
286+
test_that("DATAPTR can be obtained for s2_geography", {
287+
Rcpp::cppFunction("bool get_dataptr(SEXP obj) {
288+
return DATAPTR_RO(obj) != NULL;
289+
}")
290+
291+
expect_true(get_dataptr(as_s2_geography("POINT (0 0)")))
292+
})

0 commit comments

Comments
 (0)