[Rcpp-commits] r2469 - in pkg/Rcpp: . R inst/include/Rcpp inst/include/Rcpp/vector src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Nov 20 13:34:23 CET 2010
Author: romain
Date: 2010-11-20 13:34:22 +0100 (Sat, 20 Nov 2010)
New Revision: 2469
Modified:
pkg/Rcpp/ChangeLog
pkg/Rcpp/NAMESPACE
pkg/Rcpp/R/00_classes.R
pkg/Rcpp/R/Module.R
pkg/Rcpp/inst/include/Rcpp/Module.h
pkg/Rcpp/inst/include/Rcpp/routines.h
pkg/Rcpp/inst/include/Rcpp/vector/MatrixRow.h
pkg/Rcpp/src/Module.cpp
pkg/Rcpp/src/Rcpp_init.c
Log:
optimization in method dispatch related to void-ness of methods
Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/ChangeLog 2010-11-20 12:34:22 UTC (rev 2469)
@@ -1,3 +1,19 @@
+2010-11-20 Romain Francois <romain at r-enthusiasts.com>
+
+ * inst/include/Rcpp/vector/MatrixRow.h: added missing return *this ;
+
+ * R/Module.R: dispatch based on void-ness of the methods. For example if all
+ methods are known to be void, etc ...
+
+ * R/00_classes.R: more information in the C++OverloadedMethods ref class
+
+ * src/Module.cpp: new .External CppMethod__invoke_void and
+ CppMethod__invoke_notvoid that are used when we know for sure that all
+ overloaded methods are void, or not void
+
+ * inst/include/Rcpp/Module.h: class_ gains invoke_void and invoke_notvoid
+ to support the changes above
+
2010-11-18 Douglas Bates <bates at stat.wisc.edu>
* inst/include/Rcpp/module/Module_generated_[class_]Constructor.h:
Modified: pkg/Rcpp/NAMESPACE
===================================================================
--- pkg/Rcpp/NAMESPACE 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/NAMESPACE 2010-11-20 12:34:22 UTC (rev 2469)
@@ -18,7 +18,8 @@
rcpp_set_stack_trace, rcpp_get_stack_trace,
# .External functions
- CppMethod__invoke, InternalFunction_invoke, Module__invoke, class__newInstance
+ CppMethod__invoke, CppMethod__invoke_void, CppMethod__invoke_notvoid,
+ InternalFunction_invoke, Module__invoke, class__newInstance
)
import( methods )
Modified: pkg/Rcpp/R/00_classes.R
===================================================================
--- pkg/Rcpp/R/00_classes.R 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/R/00_classes.R 2010-11-20 12:34:22 UTC (rev 2469)
@@ -36,7 +36,9 @@
setRefClass( "C++OverloadedMethods",
fields = list(
pointer = "externalptr",
- class_pointer = "externalptr"
+ class_pointer = "externalptr",
+ size = "integer",
+ void = "logical"
)
)
Modified: pkg/Rcpp/R/Module.R
===================================================================
--- pkg/Rcpp/R/Module.R 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/R/Module.R 2010-11-20 12:34:22 UTC (rev 2469)
@@ -203,21 +203,41 @@
dealWith <- function( x ) if(isTRUE(x[[1]])) invisible(NULL) else x[[2]]
method_wrapper <- function( METHOD, where ){
- f <- function(...) NULL
- extCall <- substitute(
- {
- dealWith( .External(CppMethod__invoke, class_pointer, pointer, .pointer, ...) )
+ f <- function(...) NULL
+
+ stuff <- list(
+ class_pointer = METHOD$class_pointer,
+ pointer = METHOD$pointer,
+ CppMethod__invoke = CppMethod__invoke,
+ CppMethod__invoke_void = CppMethod__invoke_void,
+ CppMethod__invoke_notvoid = CppMethod__invoke_notvoid,
+ dealWith = dealWith
+ )
+
+ extCall <- if( all( METHOD$void ) ){
+ # all methods are void, so we know we want to return invisible(NULL)
+ substitute(
+ {
+ .External(CppMethod__invoke_void, class_pointer, pointer, .pointer, ...)
+ invisible(NULL)
+ } , stuff )
+ } else if( all( ! METHOD$void ) ){
+ # none of the methods are void so we always return the result of
+ # .External
+ substitute(
+ {
+ .External(CppMethod__invoke_notvoid, class_pointer, pointer, .pointer, ...)
+ } , stuff )
+ } else {
+ # some are void, some are not, so the voidness is part of the result
+ # we get from internally and we need to deal with it
+ substitute(
+ {
+ dealWith( .External(CppMethod__invoke, class_pointer, pointer, .pointer, ...) )
+ } , stuff )
}
- ,
- list(
- class_pointer = METHOD$class_pointer,
- pointer = METHOD$pointer,
- CppMethod__invoke = CppMethod__invoke,
- dealWith = dealWith
- )
- )
- body(f, where) <- extCall
- f
+ body(f, where) <- extCall
+ f
}
## create a named list of the R methods to invoke C++ methods
## from the C++ class with pointer xp
Modified: pkg/Rcpp/inst/include/Rcpp/Module.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/Module.h 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/inst/include/Rcpp/Module.h 2010-11-20 12:34:22 UTC (rev 2469)
@@ -71,7 +71,15 @@
virtual SEXP invoke( SEXP, SEXP, SEXP *, int ){
return R_NilValue ;
}
+ virtual SEXP invoke_void( SEXP, SEXP, SEXP *, int ){
+ return R_NilValue ;
+ }
+ virtual SEXP invoke_notvoid( SEXP, SEXP, SEXP *, int ){
+ return R_NilValue ;
+ }
+
+
virtual Rcpp::CharacterVector method_names(){ return Rcpp::CharacterVector(0) ; }
virtual Rcpp::CharacterVector property_names(){ return Rcpp::CharacterVector(0) ; }
virtual bool property_is_readonly(const std::string& ) throw(std::range_error) { return false ; }
@@ -206,8 +214,16 @@
typedef std::vector<signed_method_class*> vec_signed_method ;
S4_CppOverloadedMethods( vec_signed_method* m, SEXP class_xp ) : Reference( "C++OverloadedMethods" ){
- field( "pointer" ) = Rcpp::XPtr< vec_signed_method >( m, false ) ;
+
+ int n = m->size() ;
+ Rcpp::LogicalVector voidness( n) ;
+ for( int i=0; i<n; i++){ voidness[i] = m->at(i)->is_void() ; }
+
+ field( "pointer" ) = Rcpp::XPtr< vec_signed_method >( m, false ) ;
field( "class_pointer" ) = class_xp ;
+ field( "size" ) = n ;
+ field( "void" ) = voidness ;
+
}
} ;
@@ -354,6 +370,51 @@
END_RCPP
}
+ SEXP invoke_void( SEXP method_xp, SEXP object, SEXP *args, int nargs ){
+ BEGIN_RCPP
+
+ vec_signed_method* mets = reinterpret_cast< vec_signed_method* >( EXTPTR_PTR( method_xp ) ) ;
+ typename vec_signed_method::iterator it = mets->begin() ;
+ int n = mets->size() ;
+ method_class* m = 0 ;
+ bool ok = false ;
+ for( int i=0; i<n; i++, ++it ){
+ if( ( (*it)->valid )( args, nargs) ){
+ m = (*it)->method ;
+ ok = true ;
+ break ;
+ }
+ }
+ if( !ok ){
+ throw std::range_error( "could not find valid method" ) ;
+ }
+ m->operator()( XP(object), args );
+ END_RCPP
+ }
+
+ SEXP invoke_notvoid( SEXP method_xp, SEXP object, SEXP *args, int nargs ){
+ BEGIN_RCPP
+
+ vec_signed_method* mets = reinterpret_cast< vec_signed_method* >( EXTPTR_PTR( method_xp ) ) ;
+ typename vec_signed_method::iterator it = mets->begin() ;
+ int n = mets->size() ;
+ method_class* m = 0 ;
+ bool ok = false ;
+ for( int i=0; i<n; i++, ++it ){
+ if( ( (*it)->valid )( args, nargs) ){
+ m = (*it)->method ;
+ ok = true ;
+ break ;
+ }
+ }
+ if( !ok ){
+ throw std::range_error( "could not find valid method" ) ;
+ }
+ return m->operator()( XP(object), args ) ;
+ END_RCPP
+ }
+
+
self& AddMethod( const char* name_, method_class* m, ValidMethod valid = &yes ){
typename map_vec_signed_method::iterator it = singleton->vec_methods.find( name_ ) ;
if( it == singleton->vec_methods.end() ){
Modified: pkg/Rcpp/inst/include/Rcpp/routines.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/routines.h 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/inst/include/Rcpp/routines.h 2010-11-20 12:34:22 UTC (rev 2469)
@@ -67,6 +67,8 @@
/* .External functions */
EXTFUN(CppMethod__invoke) ;
+EXTFUN(CppMethod__invoke_void) ;
+EXTFUN(CppMethod__invoke_notvoid) ;
EXTFUN(InternalFunction_invoke) ;
EXTFUN(Module__invoke) ;
EXTFUN(class__newInstance) ;
Modified: pkg/Rcpp/inst/include/Rcpp/vector/MatrixRow.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/vector/MatrixRow.h 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/inst/include/Rcpp/vector/MatrixRow.h 2010-11-20 12:34:22 UTC (rev 2469)
@@ -132,6 +132,7 @@
default:
{}
}
+ return *this ;
}
reference operator[]( int i ){
Modified: pkg/Rcpp/src/Module.cpp
===================================================================
--- pkg/Rcpp/src/Module.cpp 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/src/Module.cpp 2010-11-20 12:34:22 UTC (rev 2469)
@@ -176,6 +176,55 @@
return clazz->invoke( met, obj, cargs, nargs ) ;
}
+extern "C" SEXP CppMethod__invoke_void(SEXP args){
+ SEXP p = CDR(args) ;
+
+ // the external pointer to the class
+ XP_Class clazz( CAR(p) ) ; p = CDR(p);
+
+ // the external pointer to the method
+ SEXP met = CAR(p) ; p = CDR(p) ;
+
+ // the external pointer to the object
+ SEXP obj = CAR(p); p = CDR(p) ;
+
+ // additional arguments, processed the same way as .Call does
+ SEXP cargs[MAX_ARGS] ;
+ int nargs = 0 ;
+ for(; nargs<MAX_ARGS; nargs++){
+ if( p == R_NilValue ) break ;
+ cargs[nargs] = CAR(p) ;
+ p = CDR(p) ;
+ }
+ clazz->invoke_void( met, obj, cargs, nargs ) ;
+ return R_NilValue ;
+}
+
+extern "C" SEXP CppMethod__invoke_notvoid(SEXP args){
+ SEXP p = CDR(args) ;
+
+ // the external pointer to the class
+ XP_Class clazz( CAR(p) ) ; p = CDR(p);
+
+ // the external pointer to the method
+ SEXP met = CAR(p) ; p = CDR(p) ;
+
+ // the external pointer to the object
+ SEXP obj = CAR(p); p = CDR(p) ;
+
+ // additional arguments, processed the same way as .Call does
+ SEXP cargs[MAX_ARGS] ;
+ int nargs = 0 ;
+ for(; nargs<MAX_ARGS; nargs++){
+ if( p == R_NilValue ) break ;
+ cargs[nargs] = CAR(p) ;
+ p = CDR(p) ;
+ }
+
+ return clazz->invoke_notvoid( met, obj, cargs, nargs ) ;
+}
+
+
namespace Rcpp{
static Module* current_scope ;
}
Modified: pkg/Rcpp/src/Rcpp_init.c
===================================================================
--- pkg/Rcpp/src/Rcpp_init.c 2010-11-20 11:47:09 UTC (rev 2468)
+++ pkg/Rcpp/src/Rcpp_init.c 2010-11-20 12:34:22 UTC (rev 2469)
@@ -69,6 +69,8 @@
static R_ExternalMethodDef extEntries[] = {
EXTDEF(CppMethod__invoke),
+ EXTDEF(CppMethod__invoke_void),
+ EXTDEF(CppMethod__invoke_notvoid),
EXTDEF(InternalFunction_invoke),
EXTDEF(Module__invoke),
EXTDEF(class__newInstance),
More information about the Rcpp-commits
mailing list