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
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
2026-10-29 Kevin Ushey <kevinushey@gmail.com>

* inst/include/Rcpp/module/class.h (class_::AddMethod): Count special
'[' methods once per name rather than once per overload, as complete()
expects; overloading '[[' dropped methods from completion or ran past
the end of the method map (#1529)
* inst/tinytest/cpp/Module.cpp: Add classes overloading '[['
* inst/tinytest/test_module.R: Test their completions

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

* DESCRIPTION (Version, Date): Roll micro version and date
Expand Down
3 changes: 2 additions & 1 deletion inst/include/Rcpp/module/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,10 @@
typename map_vec_signed_method::iterator it = ptr->vec_methods.find( name_ ) ;
if( it == ptr->vec_methods.end() ){
it = ptr->vec_methods.insert( vec_signed_method_pair( name_, new vec_signed_method() ) ).first ;
// complete() relies on this counting names, not overloads
if( *name_ == '[' ) ptr->specials++ ;
}
(it->second)->push_back( new signed_method_class(m, valid, docstring ) ) ;
if( *name_ == '[' ) ptr->specials++ ;
return *this ;
}

Expand Down
37 changes: 37 additions & 0 deletions inst/tinytest/cpp/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,27 @@ double Test_get_x_pointer(ModuleTest* x) {
return x->value;
}

class ModuleBrackets {
public:
ModuleBrackets() : value(1.0) {}

double at(int i) { return value * i; }
double at2(int i, int j) { return value * i * j; }
double total() { return value; }

double value;
};

class ModuleBracketsOnly {
public:
ModuleBracketsOnly() : value(1.0) {}

double at(int i) { return value * i; }
double at2(int i, int j) { return value * i * j; }

double value;
};

class ModuleGadget {
public:
ModuleGadget() {}
Expand Down Expand Up @@ -217,6 +238,22 @@ RCPP_MODULE(demoModule) {
.method("get" , &ModuleRandomizer::get)
;

// overloaded [[, with and without an ordinary method
class_<ModuleBrackets>("ModuleBrackets")
.constructor()
.method("[[", &ModuleBrackets::at)
.method("[[", &ModuleBrackets::at2)
.method("total", &ModuleBrackets::total)
.field("value", &ModuleBrackets::value)
;

class_<ModuleBracketsOnly>("ModuleBracketsOnly")
.constructor()
.method("[[", &ModuleBracketsOnly::at)
.method("[[", &ModuleBracketsOnly::at2)
.field("value", &ModuleBracketsOnly::value)
;

class_<ModuleGadget>("ModuleGadget")
.constructor()
.method("value", static_cast<void (ModuleGadget::*)(int)>(&ModuleGadget::value))
Expand Down
8 changes: 8 additions & 0 deletions inst/tinytest/test_module.R
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ expect_equal(r$get(10), x10)
r <- new( ModuleRandomizer )
expect_error( r$get(10L), "not initialized" )

## completion lists the ordinary methods and the fields; an overloaded [[
## used to be counted once per overload, which dropped the last ordinary
## method, or ran past the end of the method map when there was none (#1529)
brackets <- new( ModuleBrackets )
expect_equal( Rcpp:::complete( brackets ), c("total( ", "value") )
expect_equal( brackets[[2L]], 2.0 )
expect_equal( Rcpp:::complete( new( ModuleBracketsOnly ) ), "value" )

# test.Module.flexible.semantics <- function( ){
expect_equal( test_reference( seq(0,10) ), 11L )
expect_equal( test_const_reference( seq(0,10) ), 11L )
Expand Down
Loading