[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