[Rcpp-commits] r2443 - in pkg/Rcpp: . R inst/include/Rcpp man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Thu Nov 18 20:31:08 CET 2010
Author: romain
Date: 2010-11-18 20:31:06 +0100 (Thu, 18 Nov 2010)
New Revision: 2443
Removed:
pkg/Rcpp/man/CppMethod-class.Rd
Modified:
pkg/Rcpp/NAMESPACE
pkg/Rcpp/R/00_classes.R
pkg/Rcpp/R/Module.R
pkg/Rcpp/inst/include/Rcpp/Module.h
Log:
start to move towards overloaded C++ methods for an exposed class
Modified: pkg/Rcpp/NAMESPACE
===================================================================
--- pkg/Rcpp/NAMESPACE 2010-11-17 13:01:36 UTC (rev 2442)
+++ pkg/Rcpp/NAMESPACE 2010-11-18 19:31:06 UTC (rev 2443)
@@ -24,9 +24,11 @@
import( methods )
importFrom( utils, capture.output, assignInNamespace, .DollarNames, prompt, packageDescription )
-exportClasses( Module, "C++ObjectS3", "C++Field", "C++Method", "C++Constructor",
+exportClasses( Module, "C++ObjectS3", "C++Field",
+ "C++OverloadedMethods",
+ "C++Constructor",
"C++Class", "C++Object", "C++Function",
- "C++ClassRepresentation" # , "C++Property"
+ "C++ClassRepresentation"
)
S3method( .DollarNames, "C++Object" )
@@ -34,6 +36,6 @@
exportMethods( prompt, show, .DollarNames )
export(
- Module, Rcpp.package.skeleton # , setRCppClass
+ Module, Rcpp.package.skeleton
)
Modified: pkg/Rcpp/R/00_classes.R
===================================================================
--- pkg/Rcpp/R/00_classes.R 2010-11-17 13:01:36 UTC (rev 2442)
+++ pkg/Rcpp/R/00_classes.R 2010-11-18 19:31:06 UTC (rev 2443)
@@ -30,30 +30,13 @@
cpp_class = "character",
read_only = "logical",
class_pointer = "externalptr"
- ),
- methods = list(
- get = function(obj_xp){
- .Call( CppField__get, class_pointer, pointer, obj_xp )
- },
- set = function(obj_xp, value){
- .Call( CppField__set, class_pointer, pointer, obj_xp, value )
- invisible( NULL )
- }
)
)
-setRefClass( "C++Method",
+setRefClass( "C++OverloadedMethods",
fields = list(
pointer = "externalptr",
- class_pointer = "externalptr",
- void = "logical"
- # perhaps something to deal with classes of input and output
- # but this needs some work internally before
- ),
- methods = list(
- invoke = function(obj_xp, ...){
- .External( CppMethod__invoke, class_pointer, pointer, obj_xp, ... )
- }
+ class_pointer = "externalptr"
)
)
Modified: pkg/Rcpp/R/Module.R
===================================================================
--- pkg/Rcpp/R/Module.R 2010-11-17 13:01:36 UTC (rev 2442)
+++ pkg/Rcpp/R/Module.R 2010-11-18 19:31:06 UTC (rev 2443)
@@ -203,7 +203,10 @@
method_wrapper <- function( METHOD, where ){
f <- function(...) NULL
extCall <- substitute(
- .External(CppMethod__invoke, class_pointer, pointer, .pointer, ...)
+ {
+ res <- .External(CppMethod__invoke, class_pointer, pointer, .pointer, ...)
+ if(res[[1]]) invisible(NULL) else res[[2]]
+ }
,
list(
class_pointer = METHOD$class_pointer,
@@ -211,11 +214,6 @@
CppMethod__invoke = CppMethod__invoke
)
)
- if( METHOD$void )
- extCall <- substitute({
- CALL
- invisible(NULL)
- }, list(CALL = extCall))
body(f, where) <- extCall
f
}
Modified: pkg/Rcpp/inst/include/Rcpp/Module.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/Module.h 2010-11-17 13:01:36 UTC (rev 2442)
+++ pkg/Rcpp/inst/include/Rcpp/Module.h 2010-11-18 19:31:06 UTC (rev 2443)
@@ -90,7 +90,6 @@
throw std::range_error( "cannot set property" ) ;
}
-
std::string name ;
} ;
@@ -156,21 +155,11 @@
virtual bool is_void(){ return false ; }
} ;
-template <typename Class>
-class S4_CppMethod : public Rcpp::Reference {
-public:
- S4_CppMethod( CppMethod<Class>* m, SEXP class_xp ) : Reference( "C++Method" ){
- field( "void" ) = m->is_void() ;
- field( "pointer" ) = Rcpp::XPtr< CppMethod<Class> >( m, false ) ;
- field( "class_pointer" ) = class_xp ;
-
- }
-} ;
-
#include <Rcpp/module/Module_generated_Constructor.h>
#include <Rcpp/module/Module_generated_class_signature.h>
typedef bool (*ValidConstructor)(SEXP*,int) ;
+typedef bool (*ValidMethod)(SEXP*,int) ;
template <typename Class>
class SignedConstructor {
@@ -188,6 +177,19 @@
} ;
template <typename Class>
+class SignedMethod {
+public:
+ typedef CppMethod<Class> METHOD ;
+ SignedMethod( METHOD* m, ValidMethod valid_ ) : method(m), valid(valid_){}
+
+ METHOD* method ;
+ ValidMethod valid ;
+
+ inline int nargs(){ return method->nargs() ; }
+ inline bool is_void(){ return method->is_void() ; }
+} ;
+
+template <typename Class>
class S4_CppConstructor : public Rcpp::Reference {
public:
S4_CppConstructor( SignedConstructor<Class>* m, SEXP class_xp ) : Reference( "C++Constructor" ){
@@ -197,7 +199,28 @@
}
} ;
+// template <typename Class>
+// class S4_CppMethod : public Rcpp::Reference {
+// public:
+// S4_CppMethod( CppMethod<Class>* m, SEXP class_xp ) : Reference( "C++Method" ){
+// field( "void" ) = m->is_void() ;
+// field( "pointer" ) = Rcpp::XPtr< CppMethod<Class> >( m, false ) ;
+// field( "class_pointer" ) = class_xp ;
+// }
+// } ;
+template <typename Class>
+class S4_CppOverloadedMethods : public Rcpp::Reference {
+public:
+ typedef SignedMethod<Class> signed_method_class ;
+ 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 ) ;
+ field( "class_pointer" ) = class_xp ;
+ }
+} ;
+
#include <Rcpp/module/Module_generated_CppMethod.h>
#include <Rcpp/module/Module_generated_Pointer_CppMethod.h>
@@ -252,10 +275,18 @@
public:
typedef class_<Class> self ;
typedef CppMethod<Class> method_class ;
+
+ typedef SignedMethod<Class> signed_method_class ;
+ typedef std::vector<signed_method_class*> vec_signed_method ;
+ typedef std::map<std::string,vec_signed_method*> map_vec_signed_method ;
+ typedef std::pair<std::string,vec_signed_method*> vec_signed_method_pair ;
+
typedef std::map<std::string,method_class*> METHOD_MAP ;
typedef std::pair<const std::string,method_class*> PAIR ;
+
typedef Rcpp::XPtr<Class> XP ;
typedef CppFinalizer<Class> finalizer_class ;
+
typedef Constructor_Base<Class> constructor_class ;
typedef SignedConstructor<Class> signed_constructor_class ;
typedef std::vector<signed_constructor_class*> vec_signed_constructor ;
@@ -265,7 +296,7 @@
typedef std::pair<const std::string,prop_class*> PROP_PAIR ;
class_( const char* name_ ) :
- class_Base(name_), methods(), properties(), finalizer_pointer(0), specials(0), constructors()
+ class_Base(name_), vec_methods(), properties(), finalizer_pointer(0), specials(0), constructors()
{
if( !singleton ){
singleton = new self ;
@@ -308,19 +339,36 @@
SEXP invoke( SEXP method_xp, SEXP object, SEXP *args, int nargs ){
BEGIN_RCPP
- method_class* met = reinterpret_cast< method_class* >( EXTPTR_PTR( method_xp ) ) ;
- // maybe this is not needed as the R side handles it
- if( met->nargs() > nargs ){
- // Rprintf( "met->nargs() = %d\nnargs=%d\n", met->nargs(), nargs ) ;
- throw std::range_error( "incorrect number of arguments" ) ;
+
+ 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 ;
+ for( int i=0; i<n; i++, ++it ){
+ if( ( (*it)->valid )( args, nargs) ){
+ m = (*it)->method ;
+ }
}
- return met->operator()( XP(object), args );
+
+ // maybe this is not needed as the R side handles it
+ if( m == 0 ){
+ throw std::range_error( "could not find valid method" ) ;
+ }
+ if( m->is_void() ){
+ m->operator()( XP(object), args );
+ return Rcpp::List::create( true ) ;
+ } else {
+ return Rcpp::List::create( false, m->operator()( XP(object), args ) ) ;
+ }
END_RCPP
}
-
self& AddMethod( const char* name_, method_class* m){
- singleton->methods.insert( PAIR( name_,m ) ) ;
+ typename map_vec_signed_method::iterator it = singleton->vec_methods.find( name_ ) ;
+ if( it == singleton->vec_methods.end() ){
+ it = singleton->vec_methods.insert( vec_signed_method_pair( name_, new vec_signed_method() ) ).first ;
+ }
+ (it->second)->push_back( new signed_method_class(m, &yes ) ) ;
if( *name_ == '[' ) singleton->specials++ ;
return *this ;
}
@@ -334,7 +382,7 @@
#include <Rcpp/module/Module_generated_Pointer_method.h>
bool has_method( const std::string& m){
- return methods.find(m) != methods.end() ;
+ return vec_methods.find(m) != vec_methods.end() ;
}
bool has_property( const std::string& m){
return properties.find(m) != properties.end() ;
@@ -351,36 +399,69 @@
}
Rcpp::CharacterVector method_names(){
- int n = methods.size() ;
- Rcpp::CharacterVector out(n) ;
- typename METHOD_MAP::iterator it = methods.begin( ) ;
- for( int i=0; i<n; i++, ++it){
- out[i] = it->first ;
+ int n = 0 ;
+ int s = vec_methods.size() ;
+ typename map_vec_signed_method::iterator it = vec_methods.begin( ) ;
+ for( int i=0; i<s; i++, ++it){
+ n += (it->second)->size() ;
+ }
+ Rcpp::CharacterVector out(n) ;
+ it = vec_methods.begin() ;
+ int k = 0 ;
+ for( int i=0; i<s; i++, ++it){
+ n = (it->second)->size() ;
+ std::string name = it->first ;
+ for( int j=0; j<n; j++, k++){
+ out[k] = name ;
+ }
}
return out ;
}
Rcpp::IntegerVector methods_arity(){
- int n = methods.size() ;
- Rcpp::CharacterVector mnames(n) ;
- Rcpp::IntegerVector res( n );
- typename METHOD_MAP::iterator it = methods.begin( ) ;
- for( int i=0; i<n; i++, ++it){
- mnames[i] = it->first ;
- res[i] = it->second->nargs() ;
+ int n = 0 ;
+ int s = vec_methods.size() ;
+ typename map_vec_signed_method::iterator it = vec_methods.begin( ) ;
+ for( int i=0; i<s; i++, ++it){
+ n += (it->second)->size() ;
}
+ Rcpp::CharacterVector mnames(n) ;
+ Rcpp::IntegerVector res(n) ;
+ it = vec_methods.begin() ;
+ int k = 0 ;
+ for( int i=0; i<s; i++, ++it){
+ n = (it->second)->size() ;
+ std::string name = it->first ;
+ typename vec_signed_method::iterator m_it = (it->second)->begin() ;
+ for( int j=0; j<n; j++, k++, ++m_it){
+ mnames[k] = name ;
+ res[k] = (*m_it)->nargs() ;
+ }
+ }
res.names( ) = mnames ;
return res ;
}
+
Rcpp::LogicalVector methods_voidness(){
- int n = methods.size() ;
- Rcpp::CharacterVector mnames(n) ;
- Rcpp::LogicalVector res( n );
- typename METHOD_MAP::iterator it = methods.begin( ) ;
- for( int i=0; i<n; i++, ++it){
- mnames[i] = it->first ;
- res[i] = it->second->is_void() ;
+ int n = 0 ;
+ int s = vec_methods.size() ;
+ typename map_vec_signed_method::iterator it = vec_methods.begin( ) ;
+ for( int i=0; i<s; i++, ++it){
+ n += (it->second)->size() ;
}
+ Rcpp::CharacterVector mnames(n) ;
+ Rcpp::LogicalVector res(n) ;
+ it = vec_methods.begin() ;
+ int k = 0 ;
+ for( int i=0; i<s; i++, ++it){
+ n = (it->second)->size() ;
+ std::string name = it->first ;
+ typename vec_signed_method::iterator m_it = (it->second)->begin() ;
+ for( int j=0; j<n; j++, k++, ++m_it){
+ mnames[k] = name ;
+ res[k] = (*m_it)->is_void() ;
+ }
+ }
res.names( ) = mnames ;
return res ;
}
@@ -410,20 +491,21 @@
}
Rcpp::CharacterVector complete(){
- int n = methods.size() - specials ;
+ int n = vec_methods.size() - specials ;
int ntotal = n + properties.size() ;
Rcpp::CharacterVector out(ntotal) ;
- typename METHOD_MAP::iterator it = methods.begin( ) ;
+ typename map_vec_signed_method::iterator it = vec_methods.begin( ) ;
std::string buffer ;
int i=0 ;
for( ; i<n; ++it){
buffer = it->first ;
if( buffer[0] == '[' ) continue ;
- if( (it->second)->nargs() == 0){
- buffer += "() " ;
- } else {
- buffer += "( " ;
- }
+ // if( (it->second)->nargs() == 0){
+ // buffer += "() " ;
+ // } else {
+ // buffer += "( " ;
+ // }
+ buffer += "( " ;
out[i] = buffer ;
i++ ;
}
@@ -463,18 +545,19 @@
}
Rcpp::List getMethods( SEXP class_xp ){
- int n = methods.size() ;
- Rcpp::CharacterVector pnames(n) ;
- Rcpp::List out(n) ;
- typename METHOD_MAP::iterator it = methods.begin( ) ;
- for( int i=0; i<n; i++, ++it){
- pnames[i] = it->first ;
- out[i] = S4_CppMethod<Class>( it->second, class_xp ) ;
- }
- out.names() = pnames ;
- return out ;
+ int n = vec_methods.size() ;
+ Rcpp::CharacterVector mnames(n) ;
+ Rcpp::List res(n) ;
+ typename map_vec_signed_method::iterator it = vec_methods.begin( ) ;
+ vec_signed_method* v;
+ for( int i=0; i<n; i++, ++it){
+ mnames[i] = it->first ;
+ v = it->second ;
+ res[i] = S4_CppOverloadedMethods<Class>( v , class_xp ) ;
+ }
+ res.names() = mnames ;
+ return res ;
}
-
Rcpp::List getConstructors( SEXP class_xp ){
int n = constructors.size() ;
@@ -506,14 +589,14 @@
singleton->finalizer_pointer = f ;
}
- METHOD_MAP methods ;
+ map_vec_signed_method vec_methods ;
PROPERTY_MAP properties ;
static self* singleton ;
finalizer_class* finalizer_pointer ;
int specials ;
vec_signed_constructor constructors ;
- class_( ) : class_Base(), methods(), properties(), specials(0) {};
+ class_( ) : class_Base(), vec_methods(), properties(), specials(0) {};
} ;
Deleted: pkg/Rcpp/man/CppMethod-class.Rd
===================================================================
--- pkg/Rcpp/man/CppMethod-class.Rd 2010-11-17 13:01:36 UTC (rev 2442)
+++ pkg/Rcpp/man/CppMethod-class.Rd 2010-11-18 19:31:06 UTC (rev 2443)
@@ -1,27 +0,0 @@
-\name{C++Method-class}
-\Rdversion{1.1}
-\docType{class}
-\alias{C++Method-class}
-
-\title{Class "C++Method"}
-\description{
-Metadata associated with a field of a class exposed through Rcpp modules
-}
-\section{Fields}{
- \describe{
- \item{\code{pointer}:}{external pointer to the internal (C++) object that represents the method}
- \item{\code{class_pointer}:}{external pointer to the class this method is from. }
- \item{\code{void}:}{\code{TRUE} if the method is void. }
- }
-}
-\section{Methods}{
-No methods defined with class "C++Method" in the signature.
-}
-\seealso{
- The \code{fields} slot of the \code{\linkS4class{C++Class}} class is a
- list of \code{C++Method} objects
-}
-\examples{
-showClass("C++Method")
-}
-\keyword{classes}
More information about the Rcpp-commits
mailing list