[Rcpp-commits] r3839 - in pkg/Rcpp: . inst/include/Rcpp inst/include/Rcpp/module

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Oct 25 14:45:01 CEST 2012


Author: romain
Date: 2012-10-25 14:45:01 +0200 (Thu, 25 Oct 2012)
New Revision: 3839

Added:
   pkg/Rcpp/inst/include/Rcpp/module/Module_generated_Factory.h
   pkg/Rcpp/inst/include/Rcpp/module/Module_generated_class_factory.h
Modified:
   pkg/Rcpp/ChangeLog
   pkg/Rcpp/inst/include/Rcpp/Module.h
Log:
added factories (alternative to constructors)

Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog	2012-10-25 08:11:48 UTC (rev 3838)
+++ pkg/Rcpp/ChangeLog	2012-10-25 12:45:01 UTC (rev 3839)
@@ -4,7 +4,12 @@
         of the RCPP_EXPOSED_CLASS
         * include/Rcpp/module/macros.h: improving the macros so that wrap and as
         are covered
-        * include/Rcpp/traits/wrap_type_traits.h: wrapping module objects 
+        * include/Rcpp/traits/wrap_type_traits.h: wrapping module objects
+        * include/Rcpp/module/Module_generated_class_factory.h : factories are alternatives
+        to constructors. For now, we can expose as factories any free function
+        that returns a pointer to the target class
+        * include/Rcpp/module/Module_generated_Factory.h : factories
+        * include/Rcpp/Module.h: exposing factories
 
 2012-10-24  Romain Francois <romain at r-enthusiasts.com>
 

Modified: pkg/Rcpp/inst/include/Rcpp/Module.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/Module.h	2012-10-25 08:11:48 UTC (rev 3838)
+++ pkg/Rcpp/inst/include/Rcpp/Module.h	2012-10-25 12:45:01 UTC (rev 3839)
@@ -216,6 +216,8 @@
 
 #include <Rcpp/module/Module_generated_ctor_signature.h>
 #include <Rcpp/module/Module_generated_Constructor.h>
+#include <Rcpp/module/Module_generated_Factory.h>
+
 #include <Rcpp/module/Module_generated_class_signature.h>
 
     typedef bool (*ValidConstructor)(SEXP*,int) ;
@@ -240,7 +242,28 @@
             ctor->signature(buffer, class_name) ;
         }
     } ;
+    
+    template <typename Class>
+    class SignedFactory {
+    public:
+    
+        SignedFactory( 
+                          Factory_Base<Class>* fact_, 
+                          ValidConstructor valid_, 
+                          const char* doc
+                           ) : fact(fact_), valid(valid_), docstring(doc == 0 ? "" : doc){}
+    
+        Factory_Base<Class>* fact ;
+        ValidConstructor valid ;
+        std::string docstring ;
+    
+        inline int nargs(){ return fact->nargs() ; }
+        inline void signature(std::string& buffer, const std::string& class_name){ 
+            fact->signature(buffer, class_name) ;
+        }
+    } ;
 
+
     template <typename Class>
     class SignedMethod {
     public:
@@ -380,6 +403,10 @@
         typedef SignedConstructor<Class> signed_constructor_class ;
         typedef std::vector<signed_constructor_class*> vec_signed_constructor ;
         
+        typedef Factory_Base<Class> factory_class ;
+        typedef SignedFactory<Class> signed_factory_class ;
+        typedef std::vector<signed_factory_class*> vec_signed_factory ;
+        
         typedef CppProperty<Class> prop_class ;
         typedef std::map<std::string,prop_class*> PROPERTY_MAP ;
         typedef std::pair<const std::string,prop_class*> PROP_PAIR ;
@@ -390,7 +417,8 @@
             properties(), 
             finalizer_pointer(0), 
             specials(0), 
-            constructors(), 
+            constructors(),
+            factories(),
             class_pointer(0), 
             typeinfo_name("")
         {
@@ -413,11 +441,17 @@
             return *this ;
         }
         
+        self& AddFactory( factory_class* fact, ValidConstructor valid, const char* docstring = 0 ){
+            class_pointer->factories.push_back( new signed_factory_class( fact, valid, docstring ) ) ;
+            return *this ;
+        }
+        
         self& default_constructor( const char* docstring= 0, ValidConstructor valid = &yes_arity<0> ){
             return constructor( docstring, valid ) ;  
         }
                 
 #include <Rcpp/module/Module_generated_class_constructor.h>
+#include <Rcpp/module/Module_generated_class_factory.h>
         
     public:
         
@@ -437,6 +471,18 @@
                     return XP( ptr, true ) ;
                 }
             }
+            
+            signed_factory_class* pfact ;
+            n = factories.size() ;
+            for( int i=0; i<n; i++){
+              pfact = factories[i] ;
+              bool ok = (pfact->valid)(args, nargs) ;
+              if( ok ){
+                Class* ptr = pfact->fact->get_new( args, nargs ) ;
+                return XP( ptr, true ) ;
+              }
+            }
+            
             throw std::range_error( "no valid constructor available for the argument list" ) ;
             END_RCPP
                 }
@@ -448,6 +494,12 @@
                 p = constructors[i];
                 if( p->nargs() == 0 ) return true ;
             }
+            n = factories.size() ;
+            signed_factory_class* pfact ;
+            for( int i=0; i<n; i++ ){
+                pfact = factories[i];
+                if( pfact->nargs() == 0 ) return true ;
+            }
             return false ;
         }
         
@@ -755,10 +807,11 @@
         finalizer_class* finalizer_pointer ;
         int specials ;
         vec_signed_constructor constructors ;
+        vec_signed_factory factories ;
         self* class_pointer ;
         std::string typeinfo_name ;
     
-        class_( ) : class_Base(), vec_methods(), properties(), specials(0) {}; 
+        class_( ) : class_Base(), vec_methods(), properties(), specials(0), constructors(), factories() {}; 
         
     } ;   
 

Added: pkg/Rcpp/inst/include/Rcpp/module/Module_generated_Factory.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/module/Module_generated_Factory.h	                        (rev 0)
+++ pkg/Rcpp/inst/include/Rcpp/module/Module_generated_Factory.h	2012-10-25 12:45:01 UTC (rev 3839)
@@ -0,0 +1,179 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// Module_generated_Factory.h: Rcpp R/C++ interface class library -- Rcpp module class factories
+//
+// Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois
+//
+// This file is part of Rcpp.
+//
+// Rcpp is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Rcpp is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef Rcpp_Module_generated_Factory_h
+#define Rcpp_Module_generated_Factory_h
+   
+template <typename Class>
+class Factory_Base {
+public:
+    virtual Class* get_new( SEXP* args, int nargs ) = 0 ;
+    virtual int nargs() = 0 ;
+    virtual void signature(std::string& s, const std::string& class_name) = 0 ;
+} ;
+
+template <typename Class>
+class Factory_0 : public Factory_Base<Class>{
+  public: 
+    Factory_0( Class* (*fun)(void) ) : ptr_fun(fun){}
+    virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun() ;
+    }
+    virtual int nargs(){ return 0 ; }
+    virtual void signature(std::string& s, const std::string& class_name ){
+        ctor_signature(s, class_name) ;
+    }
+  private:
+    Class* (*ptr_fun)(void) ;
+} ;        
+template <typename Class, typename U0>
+class Factory_1 : public Factory_Base<Class>{
+public:
+  Factory_1( Class* (*fun)(U0) ) :ptr_fun(fun){}
+  virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun( as<U0>(args[0]) ) ;
+  }
+  virtual int nargs(){ return 1 ; }
+  virtual void signature(std::string& s, const std::string& class_name ){
+      ctor_signature<U0>(s, class_name) ;
+  }
+private:
+  Class* (*ptr_fun)(U0) ;
+} ;
+template <typename Class, typename U0, typename U1>
+class Factory_2 : public Factory_Base<Class>{
+public:
+  Factory_2( Class* (*fun)(U0, U1) ) :ptr_fun(fun){}
+  virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun( 
+          as<U0>(args[0]), 
+          as<U1>(args[1]) 
+          ) ;
+  }
+  virtual int nargs(){ return 2 ; }
+  virtual void signature(std::string& s, const std::string& class_name ){
+      ctor_signature<U0,U1>(s, class_name) ;
+  }
+private:
+  Class* (*ptr_fun)(U0, U1) ;   
+} ;
+template <typename Class, typename U0, typename U1, typename U2>
+class Factory_3 : public Factory_Base<Class>{
+public:
+  Factory_3( Class* (*fun)(U0, U1, U2) ) :ptr_fun(fun){} 
+  virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun( 
+          as<U0>(args[0]), 
+          as<U1>(args[1]), 
+          as<U2>(args[2]) 
+          ) ;
+  }
+  virtual int nargs(){ return 3 ; }
+  virtual void signature(std::string& s, const std::string& class_name ){
+      ctor_signature<U0,U1,U2>(s, class_name) ;
+  }
+private:
+  Class* (*ptr_fun)(U0, U1, U2) ;
+} ;
+template <typename Class, typename U0, typename U1, typename U2, typename U3>
+class Factory_4 : public Factory_Base<Class>{
+public:
+  Factory_4( Class* (*fun)(U0, U1, U2, U3) ) :ptr_fun(fun){} 
+  virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun( 
+          as<U0>(args[0]), 
+          as<U1>(args[1]), 
+          as<U2>(args[2]), 
+          as<U3>(args[3]) 
+          ) ;
+  }
+  virtual int nargs(){ return 4 ; }
+  virtual void signature(std::string& s, const std::string& class_name ){
+      ctor_signature<U0,U1,U2,U3>(s, class_name) ;
+  }
+private:
+  Class* (*ptr_fun)(U0, U1, U2, U3) ;
+} ;
+template <typename Class, typename U0, typename U1, typename U2, typename U3, typename U4>
+class Factory_5 : public Factory_Base<Class>{
+public:
+  Factory_5( Class* (*fun)(U0, U1, U2, U3, U4) ) :ptr_fun(fun){} 
+  virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun( 
+          as<U0>(args[0]), 
+          as<U1>(args[1]), 
+          as<U2>(args[2]), 
+          as<U3>(args[3]), 
+          as<U4>(args[4]) 
+          ) ;
+  }
+  virtual int nargs(){ return 5 ; }
+  virtual void signature(std::string& s, const std::string& class_name ){
+      ctor_signature<U0,U1,U2,U3,U4>(s, class_name) ;
+  }
+private:
+  Class* (*ptr_fun)(U0, U1, U2, U3, U4) ;
+} ;
+template <typename Class, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5>
+class Factory_6 : public Factory_Base<Class>{
+public:
+  Factory_6( Class* (*fun)(U0, U1, U2, U3, U4, U5) ) :ptr_fun(fun){} 
+  virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun( 
+          as<U0>(args[0]), 
+          as<U1>(args[1]), 
+          as<U2>(args[2]), 
+          as<U3>(args[3]), 
+          as<U4>(args[4]),
+          as<U5>(args[5]) 
+          ) ;
+  }
+  virtual int nargs(){ return 6 ; }
+  virtual void signature(std::string& s, const std::string& class_name ){
+      ctor_signature<U0,U1,U2,U3,U4,U5>(s, class_name) ;
+  }
+private:
+  Class* (*ptr_fun)(U0, U1, U2, U3, U4, U5) ;
+} ;
+template <typename Class, typename U0, typename U1, typename U2, typename U3, typename U4, typename U5, typename U6>
+class Factory_7 : public Factory_Base<Class>{
+public:
+  Factory_7( Class* (*fun)(U0, U1, U2, U3, U4, U5, U6) ) :ptr_fun(fun){} 
+  virtual Class* get_new( SEXP* args, int nargs ){
+      return ptr_fun( 
+          as<U0>(args[0]), 
+          as<U1>(args[1]), 
+          as<U2>(args[2]), 
+          as<U3>(args[3]), 
+          as<U4>(args[4]),
+          as<U5>(args[5]),
+          as<U6>(args[6]) 
+          ) ;
+  }
+  virtual int nargs(){ return 7 ; }
+  virtual void signature(std::string& s, const std::string& class_name ){
+      ctor_signature<U0,U1,U2,U3,U4,U5,U6>(s, class_name) ;
+  }
+private:
+   Class* (*ptr_fun)(U0, U1, U2, U3, U4, U5, U6) ;
+} ;
+
+#endif

Added: pkg/Rcpp/inst/include/Rcpp/module/Module_generated_class_factory.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/module/Module_generated_class_factory.h	                        (rev 0)
+++ pkg/Rcpp/inst/include/Rcpp/module/Module_generated_class_factory.h	2012-10-25 12:45:01 UTC (rev 3839)
@@ -0,0 +1,108 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// Module_generated_class_factory.h: Rcpp R/C++ interface class library -- alternative way to declare constructors
+//
+// Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois
+//
+// This file is part of Rcpp.
+//
+// Rcpp is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Rcpp is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//                                                       
+// You should have received a copy of the GNU General Public License
+// along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef Rcpp_Module_generated_class_factory_h
+#define Rcpp_Module_generated_class_factory_h
+
+    template <
+        typename U0, 
+        typename U1, 
+        typename U2, 
+        typename U3, 
+        typename U4, 
+        typename U5,
+        typename U6
+    > 
+    self& factory( Class* (*fun)(U0,U1,U2,U3,U4,U5,U6), const char* docstring = 0, ValidConstructor valid = &yes_arity<7> ){
+        AddFactory( new Factory_7<Class,U0,U1,U2,U3,U4,U5,U6>(fun) , valid, docstring ) ;
+        return *this ;   
+    }
+
+    template <
+        typename U0, 
+        typename U1, 
+        typename U2, 
+        typename U3, 
+        typename U4, 
+        typename U5
+    > 
+    self& factory( Class* (*fun)(U0,U1,U2,U3,U4,U5), const char* docstring = 0, ValidConstructor valid = &yes_arity<6> ){
+        AddFactory( new Factory_6<Class,U0,U1,U2,U3,U4,U5>(fun) , valid, docstring ) ;
+        return *this ;   
+    }
+
+    template <
+        typename U0, 
+        typename U1, 
+        typename U2, 
+        typename U3, 
+        typename U4
+    > 
+    self& factory( Class* (*fun)(U0,U1,U2,U3,U4), const char* docstring = 0, ValidConstructor valid = &yes_arity<5>){
+        AddFactory( new Factory_5<Class,U0,U1,U2,U3,U4>(fun) , valid, docstring ) ;
+        return *this ;   
+    }
+
+    template <
+        typename U0, 
+        typename U1, 
+        typename U2, 
+        typename U3
+    > 
+    self& factory( Class* (*fun)(U0,U1,U2,U3), const char* docstring="", ValidConstructor valid = &yes_arity<4>){
+        AddFactory( new Factory_4<Class,U0,U1,U2,U3>(fun) , valid, docstring ) ;
+        return *this ;   
+    }
+
+
+    template <
+        typename U0, 
+        typename U1, 
+        typename U2
+    > 
+    self& factory( Class* (*fun)(U0,U1,U2), const char* docstring="",  ValidConstructor valid = &yes_arity<3>){
+        AddFactory( new Factory_3<Class,U0,U1,U2>(fun) , valid, docstring ) ;
+        return *this ;   
+    }
+
+    template <
+        typename U0, 
+        typename U1
+    > 
+    self& factory( Class* (*fun)(U0,U1), const char* docstring="", ValidConstructor valid = &yes_arity<2>){
+        AddFactory( new Factory_2<Class,U0,U1>(fun) , valid, docstring ) ;
+        return *this ;   
+    }
+ 
+    template <
+        typename U0
+    > 
+    self& factory( Class* (*fun)(U0), const char* docstring="", ValidConstructor valid = &yes_arity<1>){
+        AddFactory( new Factory_1<Class,U0>(fun) , valid, docstring ) ;
+        return *this ;   
+    }
+    
+    self& factory( Class* (*fun)(void), const char* docstring="", ValidConstructor valid = &yes_arity<0>){
+        AddFactory( new Factory_0<Class>(fun), valid , docstring) ;
+        return *this ;
+    }
+    
+#endif



More information about the Rcpp-commits mailing list