Skip to content
Merged
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
21 changes: 21 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
2026-10-21 Michael Sumner <mdsumner@gmail.com>

* R/Module.R (Module): Supply the 'initialize' method to setRefClass() with
the other methods instead of adding it in a second generator$methods()
call, which repeated the reference class analysis of every exposed
method, and reuse the C++Class objects returned by
Module__classes_info() rather than rebuilding each of them via
.get_Module_Class(); both reduce the time spent loading a module (#1515)
* R/Module.R (Module): Take the class representation from the generator
rather than looking it up by name with methods::getClass(), which
ignores 'where' and can return another loaded package's class of the same
name
* R/Module.R (Module): Register as(FROM, TO) converters after the loop
that populates 'storage' rather than once per function inside it
* R/Module.R (Module): Match the 'show' method name exactly rather than as
a substring, so a class exposing e.g. 'showInfo' keeps the C++Object show
method

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always appreciate additions to ChangeLog; I try to keep each bullet point to two lines but we can do that in a post-processing step.


* DESCRIPTION (Version, Date): Roll micro version and date
* inst/include/Rcpp/config.h: Idem

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

* DESCRIPTION (Version, Date): Roll micro version and date
Expand Down
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: Rcpp
Title: Seamless R and C++ Integration
Version: 1.1.2.5
Date: 2026-10-13
Version: 1.1.2.6
Date: 2026-10-21

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually do this on our end but this is also a reasonable snapshot so thanks here too.

Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org",
comment = c(ORCID = "0000-0001-6419-907X")),
person("Romain", "Francois", role = "aut",
Expand Down
56 changes: 29 additions & 27 deletions R/Module.R
Original file line number Diff line number Diff line change
Expand Up @@ -222,26 +222,28 @@ Module <- function( module, PACKAGE = methods::getPackageName(where), where = to

fields <- cpp_fields( CLASS, where )
methods <- cpp_refMethods(CLASS, where)
generator <- methods::setRefClass( clname,
fields = fields,
contains = "C++Object",
methods = methods,
where = where
)
# just to make codetools happy
.self <- .refClassDef <- NULL
generator$methods(initialize =
# Supply 'initialize' together with the other methods so that the
# reference class is analysed once, instead of a second full pass
# through refClassInformation() in generator$methods(...)
methods[["initialize"]] <-
if (cpp_hasDefaultConstructor(CLASS))
function(...) Rcpp::cpp_object_initializer(.self,.refClassDef, ...)
else
function(...) {
if (nargs()) Rcpp::cpp_object_initializer(.self,.refClassDef, ...)
else Rcpp::cpp_object_dummy(.self, .refClassDef) # #nocov
}
)
rm( .self, .refClassDef )
generator <- methods::setRefClass( clname,
fields = fields,
contains = "C++Object",
methods = methods,
where = where
)

classDef <- methods::getClass(clname)
classDef <- generator$def
## non-public (static) fields in class representation
## <fixme> Should these become real fields? </fixme>
fields <- classDef@fieldPrototypes
Expand All @@ -268,7 +270,7 @@ Module <- function( module, PACKAGE = methods::getPackageName(where), where = to
} # #nocov end

# promoting show to S4
if( any( grepl( "show", names(CLASS@methods) ) ) ){
if( "show" %in% names(CLASS@methods) ){
setMethod( "show", clname, function(object) object$show(), where = where ) # #nocov
}

Expand All @@ -281,7 +283,10 @@ Module <- function( module, PACKAGE = methods::getPackageName(where), where = to
CLASS <- classes[[i]]
clname <- CLASS@.Data
demangled_name <- sub( "^Rcpp_", "", clname )
.classes_map[[ CLASS@typeid ]] <- storage[[ demangled_name ]] <- .get_Module_Class( module, demangled_name, xp )
# reuse the C++Class object already built by Module__classes_info
# rather than rebuilding it (and all of its method/field objects)
CLASS@generator <- generators[[ clname ]]
.classes_map[[ CLASS@typeid ]] <- storage[[ demangled_name ]] <- CLASS

# exposing enums values as CLASS.VALUE
# (should really be CLASS$value but I don't know how to do it)
Expand All @@ -299,24 +304,21 @@ Module <- function( module, PACKAGE = methods::getPackageName(where), where = to
functions <- .Call( Module__functions_names, xp )
for( fun in functions ){
storage[[ fun ]] <- .get_Module_function( module, fun, xp )

# register as(FROM, TO) methods
converter_rx <- "^[.]___converter___(.*)___(.*)$"
if( length( matches <- grep( converter_rx, functions ) ) ){ # #nocov start
for( i in matches ){
fun <- functions[i]
from <- sub( converter_rx, "\\1", fun )
to <- sub( converter_rx, "\\2", fun )
converter <- function( from ){}
body( converter ) <- substitute( { CONVERT(from) },
list( CONVERT = storage[[fun]] )
)
setAs( from, to, converter, where = where )
}
} # #nocov end

}

# register as(FROM, TO) methods once storage holds every function: the
# converter body captures storage[[fun]] by value via substitute()
converter_rx <- "^[.]___converter___(.*)___(.*)$"
for( fun in grep( converter_rx, functions, value = TRUE ) ){ # #nocov start
from <- sub( converter_rx, "\\1", fun )
to <- sub( converter_rx, "\\2", fun )
converter <- function( from ){}
body( converter ) <- substitute( { CONVERT(from) },
list( CONVERT = storage[[fun]] )
)
setAs( from, to, converter, where = where )
} # #nocov end

assign( "storage", storage, envir = as.environment(module) )
module
}
Expand Down
4 changes: 2 additions & 2 deletions inst/include/Rcpp/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
#define RCPP_VERSION_STRING "1.1.2"

// the current source snapshot (using four components, if a fifth is used in DESCRIPTION we ignore it)
#define RCPP_DEV_VERSION RcppDevVersion(1,1,2,5)
#define RCPP_DEV_VERSION_STRING "1.1.2.5"
#define RCPP_DEV_VERSION RcppDevVersion(1,1,2,6)
#define RCPP_DEV_VERSION_STRING "1.1.2.6"

// Whether sugar checks that the operands of an expression, and a vector
// assigned into a range, row or column, have matching lengths. On by default
Expand Down
Loading