Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2026-10-29 Kevin Ushey <kevinushey@gmail.com>

* inst/include/Rcpp/module/Module_Add_Property.h: Return *this from
the property() overload taking a free-function getter and a member
function setter, which fell off the end and trapped at module load
(#1519)
* inst/tinytest/cpp/Module.cpp: Expose one property per property()
overload
* inst/tinytest/test_module.R: Test them

2026-10-23 Dirk Eddelbuettel <edd@debian.org>

* DESCRIPTION (Version, Date): Roll micro version and date
Expand Down
1 change: 1 addition & 0 deletions inst/include/Rcpp/module/Module_Add_Property.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
name_,
new CppProperty_GetPointer_SetMethod<Class,PROP>(GetMethod, SetMethod, docstring)
) ;
return *this ;
}

template <typename PROP>
Expand Down
33 changes: 33 additions & 0 deletions inst/tinytest/cpp/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ class ModuleNum{
int y;
};

class ModuleProperties {
public:
ModuleProperties() : value(0.0) {}

double get() { return value; }
double get_const() const { return value; }
void set(double value_) { value = value_; }

double value;
};

double ModuleProperties_get(ModuleProperties* p) {
return p->value;
}
void ModuleProperties_set(ModuleProperties* p, double value) {
p->value = value;
}

class ModuleNumber{
public:
ModuleNumber() : x(0.0), y(0) {};
Expand Down Expand Up @@ -193,6 +211,21 @@ RCPP_MODULE(demoModule) {
.property("y", &ModuleNum::getY)
;

// one property per class_::property() overload: getters are member,
// const member or free functions, setters are member or free functions
class_<ModuleProperties>("ModuleProperties")
.constructor()
.property("get", &ModuleProperties::get)
.property("get_const", &ModuleProperties::get_const)
.property("get_free", &ModuleProperties_get, "free getter")
.property("get_set", &ModuleProperties::get, &ModuleProperties::set)
.property("get_const_set", &ModuleProperties::get_const, &ModuleProperties::set)
.property("get_set_free", &ModuleProperties::get, &ModuleProperties_set)
.property("get_const_set_free", &ModuleProperties::get_const, &ModuleProperties_set)
.property("get_free_set", &ModuleProperties_get, &ModuleProperties::set)
.property("get_free_set_free", &ModuleProperties_get, &ModuleProperties_set)
;

class_<ModuleNumber>("ModuleNumber")

.constructor()
Expand Down
21 changes: 21 additions & 0 deletions inst/tinytest/test_module.R
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,27 @@ expect_equal( w$x, 2.0 )

expect_error( { w$y <- 3 } )

## every class_::property() overload; the free getter + member setter one
## did not return *this, which aborted loading the whole module (#1519)
p <- new( ModuleProperties )
p$get_set <- 1.0
expect_equal( p$get_set, 1.0 )
p$get_const_set <- 2.0
expect_equal( p$get_const_set, 2.0 )
p$get_set_free <- 3.0
expect_equal( p$get_set_free, 3.0 )
p$get_const_set_free <- 4.0
expect_equal( p$get_const_set_free, 4.0 )
p$get_free_set <- 5.0
expect_equal( p$get_free_set, 5.0 )
p$get_free_set_free <- 6.0
expect_equal( p$get_free_set_free, 6.0 )

expect_equal( c(p$get, p$get_const, p$get_free), c(6.0, 6.0, 6.0) )
expect_error( { p$get <- 7.0 } )
expect_error( { p$get_const <- 7.0 } )
expect_error( { p$get_free <- 7.0 } )

# test.Module.member <- function(){
w <- new( ModuleNumber )
expect_equal( w$x, 0.0 )
Expand Down
Loading