diff --git a/ChangeLog b/ChangeLog index 402732946..c25c3c379 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2026-10-29 Kevin Ushey + + * 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 * DESCRIPTION (Version, Date): Roll micro version and date diff --git a/inst/include/Rcpp/module/Module_Add_Property.h b/inst/include/Rcpp/module/Module_Add_Property.h index 5865a5719..778c3645e 100644 --- a/inst/include/Rcpp/module/Module_Add_Property.h +++ b/inst/include/Rcpp/module/Module_Add_Property.h @@ -83,6 +83,7 @@ name_, new CppProperty_GetPointer_SetMethod(GetMethod, SetMethod, docstring) ) ; + return *this ; } template diff --git a/inst/tinytest/cpp/Module.cpp b/inst/tinytest/cpp/Module.cpp index 7f3132820..4e7f94a4b 100644 --- a/inst/tinytest/cpp/Module.cpp +++ b/inst/tinytest/cpp/Module.cpp @@ -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) {}; @@ -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") + .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") .constructor() diff --git a/inst/tinytest/test_module.R b/inst/tinytest/test_module.R index db0edfc60..95fc9e43c 100644 --- a/inst/tinytest/test_module.R +++ b/inst/tinytest/test_module.R @@ -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 )