Rcpp Version 0.10.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
Module.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // Module.h: Rcpp R/C++ interface class library -- Rcpp modules
4 //
5 // Copyright (C) 2010 - 2012 Dirk Eddelbuettel and Romain Francois
6 //
7 // This file is part of Rcpp.
8 //
9 // Rcpp is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Rcpp is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21 
22 #ifndef Rcpp_Module_h
23 #define Rcpp_Module_h
24 
25 #include <Rcpp/config.h>
26 
27 namespace Rcpp{
28 
29  namespace internal{
30 
31  template <typename FROM, typename TO>
32  std::string get_converter_name(const char* from, const char* to){
33  std::string method_name( ".___converter___" ) ;
36  method_name += "Rcpp_" ;
37  }
38  method_name += from ;
39  method_name += "___" ;
42  method_name += "Rcpp_" ;
43  }
44  method_name += to ;
45 
46  return method_name ;
47  }
48 
49 
50  }
51 
52  class CppClass ;
53  class CppObject ;
54 
55  template <typename T>
56  class result {
57  public:
58  result( T* ptr_ ) : ptr(ptr_){}
59  operator T*(){ return ptr ; }
60  private:
61  T* ptr;
62  } ;
63 
64  template <typename T>
65  class object {
66  public:
67  typedef T object_type ;
68  object( T* ptr_ ) : ptr(ptr_){}
69  operator T*(){ return ptr ; }
70  T* operator->(){ return ptr ; }
71  T& operator&(){ return *ptr ; }
72  T* ptr ;
73  } ;
74 
75  namespace internal {
76  template <typename Class>
77  SEXP make_new_object( Class* ptr ){
78  Rcpp::XPtr<Class> xp( ptr, true ) ;
79  Function maker = Environment::Rcpp_namespace()[ "cpp_object_maker"] ;
80  return maker( typeid(Class).name() , xp ) ;
81  }
82  }
83 
85 #include <Rcpp/module/Module_generated_get_return_type.h>
86 #include <Rcpp/module/Module_generated_get_signature.h>
87 
88  // templates CppFunction0, ..., CppFunction65
89 #include <Rcpp/module/Module_generated_CppFunction.h>
90 #include <Rcpp/module/class_Base.h>
91 #include <Rcpp/module/Module.h>
92 }
93 extern "C" Rcpp::Module* getCurrentScope() ;
94 extern "C" void setCurrentScope( Rcpp::Module* ) ;
95 
96 namespace Rcpp{
97 
98  template <typename Class>
99  class CppMethod {
100  public:
102 
104  virtual SEXP operator()(Class* object, SEXP* args) { return R_NilValue ; }
105  virtual ~CppMethod(){}
106  virtual int nargs(){ return 0 ; }
107  virtual bool is_void(){ return false ; }
108  virtual bool is_const(){ return false ; }
109  virtual void signature(std::string& s, const char* name ){ s = name ; }
110  } ;
111 
112  template <typename Class, typename Parent>
113  class CppInheritedMethod : public CppMethod<Class> {
114  public:
117 
118  CppInheritedMethod( ParentMethod* parent_method_pointer_ ) :
119  parent_method_pointer(parent_method_pointer_)
120  {}
121 
122  SEXP operator()( Class* object, SEXP* args){
123  return (*parent_method_pointer)( (Parent*)object, args ) ;
124  }
125  inline int nargs(){ return parent_method_pointer->nargs() ; }
126  inline bool is_void(){ return parent_method_pointer->is_void() ; }
127  inline bool is_const(){ return parent_method_pointer->is_const() ; }
128  inline void signature(std::string& s, const char* name){ return parent_method_pointer->signature(s, name) ; }
129 
130  private:
132  } ;
133 
134 #include <Rcpp/module/Module_generated_ctor_signature.h>
135 #include <Rcpp/module/Module_generated_Constructor.h>
136 #include <Rcpp/module/Module_generated_Factory.h>
137 
138 #include <Rcpp/module/Module_generated_class_signature.h>
139 
140  typedef bool (*ValidConstructor)(SEXP*,int) ;
141  typedef bool (*ValidMethod)(SEXP*,int) ;
142 
143  template <typename Class>
145  public:
146 
148  Constructor_Base<Class>* ctor_,
149  ValidConstructor valid_,
150  const char* doc
151  ) : ctor(ctor_), valid(valid_), docstring(doc == 0 ? "" : doc){}
152 
153  Constructor_Base<Class>* ctor ;
155  std::string docstring ;
156 
157  inline int nargs(){ return ctor->nargs() ; }
158  inline void signature(std::string& buffer, const std::string& class_name){
159  ctor->signature(buffer, class_name) ;
160  }
161  } ;
162 
163  template <typename Class>
165  public:
166 
168  Factory_Base<Class>* fact_,
169  ValidConstructor valid_,
170  const char* doc
171  ) : fact(fact_), valid(valid_), docstring(doc == 0 ? "" : doc){}
172 
173  Factory_Base<Class>* fact ;
175  std::string docstring ;
176 
177  inline int nargs(){ return fact->nargs() ; }
178  inline void signature(std::string& buffer, const std::string& class_name){
179  fact->signature(buffer, class_name) ;
180  }
181  } ;
182 
183 
184  template <typename Class>
185  class SignedMethod {
186  public:
188  SignedMethod( METHOD* m, ValidMethod valid_, const char* doc ) : method(m), valid(valid_), docstring(doc == 0 ? "" : doc) {}
189 
192  std::string docstring ;
193 
194  inline int nargs(){ return method->nargs() ; }
195  inline bool is_void(){ return method->is_void() ; }
196  inline bool is_const(){ return method->is_const() ; }
197  inline void signature(std::string& s, const char* name){
198  method->signature(s, name);
199  }
200 
201  } ;
202 
203  template <typename Class>
205  public:
207 
208  S4_CppConstructor( SignedConstructor<Class>* m, const XP_Class& class_xp, const std::string& class_name, std::string& buffer ) : Reference( "C++Constructor" ){
209  RCPP_DEBUG( "S4_CppConstructor( SignedConstructor<Class>* m, SEXP class_xp, const std::string& class_name, std::string& buffer" ) ;
210  field( "pointer" ) = Rcpp::XPtr< SignedConstructor<Class> >( m, false ) ;
211  field( "class_pointer" ) = class_xp ;
212  field( "nargs" ) = m->nargs() ;
213  m->signature( buffer, class_name ) ;
214  field( "signature" ) = buffer ;
215  field( "docstring" ) = m->docstring ;
216  }
217 
218  S4_CppConstructor( const S4_CppConstructor& other) : Reference( other.asSexp() ) {}
220  setSEXP( other.asSexp() );
221  return *this ;
222  }
223  } ;
224 
225  template <typename Class>
227  public:
230  typedef std::vector<signed_method_class*> vec_signed_method ;
231 
232  // FIXME: is class_xp protected ?
233  S4_CppOverloadedMethods( vec_signed_method* m, const XP_Class& class_xp, const char* name, std::string& buffer ) : Reference( "C++OverloadedMethods" ){
234  RCPP_DEBUG_2( "S4_CppOverloadedMethods( vec_signed_method* m, const XP_Class& class_xp = <%p>, const char* name = %s, std::string& buffer )", name, class_xp.asSexp() )
235  #if RCPP_DEBUG_LEVEL > 0
236  Rf_PrintValue( class_xp ) ;
237  #endif
238 
239  int n = m->size() ;
240  Rcpp::LogicalVector voidness(n), constness(n) ;
241  Rcpp::CharacterVector docstrings(n), signatures(n) ;
242  Rcpp::IntegerVector nargs(n) ;
243  signed_method_class* met ;
244  for( int i=0; i<n; i++){
245  met = m->at(i) ;
246  nargs[i] = met->nargs() ;
247  voidness[i] = met->is_void() ;
248  constness[i] = met->is_const() ;
249  docstrings[i] = met->docstring ;
250  met->signature(buffer, name) ;
251  signatures[i] = buffer ;
252  }
253 
254  field( "pointer" ) = Rcpp::XPtr< vec_signed_method >( m, false ) ;
255  field( "class_pointer" ) = class_xp ;
256  field( "size" ) = n ;
257  field( "void" ) = voidness ;
258  field( "const" ) = constness ;
259  field( "docstrings" ) = docstrings ;
260  field( "signatures" ) = signatures ;
261  field( "nargs" ) = nargs ;
262 
263  }
265  setSEXP( other.asSexp() ) ;
266  }
268  setSEXP( other.asSexp() ) ;
269  return *this ;
270  }
271  } ;
272 
273 #include <Rcpp/module/Module_generated_CppMethod.h>
274 #include <Rcpp/module/Module_generated_Pointer_CppMethod.h>
275 
276  template <typename Class>
277  class CppProperty {
278  public:
280 
281  CppProperty(const char* doc = 0) : docstring( doc == 0 ? "" : doc ) {} ;
282  virtual ~CppProperty(){} ;
283  virtual SEXP get(Class* ) { throw std::range_error("cannot retrieve property"); }
284  virtual void set(Class*, SEXP) { throw std::range_error("cannot set property"); }
285  virtual bool is_readonly(){ return false; }
286  virtual std::string get_class(){ return ""; }
287 
288  std::string docstring ;
289  } ;
290 
291  template <typename Class, typename Parent>
292  class CppInheritedProperty : public CppProperty<Class> {
293  public:
295 
297  Base( parent_property_->docstring.c_str() ),
298  parent_property(parent_property_)
299  {}
300 
301  SEXP get( Class* obj ){ return parent_property->get( (Parent*)obj ) ; }
302  void set( Class* obj, SEXP s) { parent_property->set( (Parent*)obj, s ) ; }
304  std::string get_class(){ return parent_property->get_class() ; }
305 
306  private:
308  } ;
309 
310  template <typename Class>
311  class CppFinalizer{
312  public:
314  virtual void run(Class* ){} ;
315  } ;
316 
317  template <typename Class>
318  class FunctionFinalizer : public CppFinalizer<Class> {
319  public:
320  typedef void (*Pointer)(Class*) ;
322 
323  virtual void run(Class* object){
324  finalizer( object ) ;
325  }
326 
327  private:
329  } ;
330 
331  template <typename Class>
332  class S4_field : public Rcpp::Reference {
333  public:
335  S4_field( CppProperty<Class>* p, const XP_Class& class_xp ) : Reference( "C++Field" ){
336  RCPP_DEBUG( "S4_field( CppProperty<Class>* p, const XP_Class& class_xp )" )
337  field( "read_only" ) = p->is_readonly() ;
338  field( "cpp_class" ) = p->get_class();
339  field( "pointer" ) = Rcpp::XPtr< CppProperty<Class> >( p, false ) ;
340  field( "class_pointer" ) = class_xp ;
341  field( "docstring" ) = p->docstring ;
342  }
343  S4_field( const S4_field& other) : Reference(other.asSexp()) {}
344  S4_field& operator=(const S4_field& other){
345  setSEXP(other.asSexp());
346  return *this ;
347  }
348  } ;
349 
351 
352 #include <Rcpp/module/class.h>
353 
354  template <typename Enum, typename Parent>
355  class enum_ {
356  public:
358 
359  enum_( const char* name_ ) :
360  name(name_), values(), parent_typeinfo_name( typeid(Parent).name() ){
361  }
363  Rcpp::Module* module = getCurrentScope() ;
364  module->add_enum( parent_typeinfo_name, name, values ) ;
365  }
366 
367  self& value( const char* name_, Enum value_ ){
368  values.insert( PAIR( name_, static_cast<int>( value_ ) ) ) ;
369  return *this ;
370  }
371 
372  private:
373 
374  std::string name ;
375  typedef std::map< std::string, int > MAP ;
376  typedef MAP::value_type PAIR ;
378  std::string parent_typeinfo_name ;
379 
380  } ;
381 
382  // function factories
383 #include <Rcpp/module/Module_generated_function.h>
384 
385  template <typename FROM, typename TO>
386  void converter( const char* from, const char* to, TO (*fun)(FROM), const char* docstring = 0 ){
387  std::string fun_name = internal::get_converter_name<FROM,TO>( from, to ) ;
388  function( fun_name.c_str(), fun, docstring ) ;
389  }
390 
391  // commented out as there is no convert_to in class_
392  //
393  // template <typename FROM, typename TO>
394  // void converter( const char* /* from */ , const char* to, TO (FROM::*fun)(), const char* docstring = 0 ){
395  // class_<FROM>().convert_to( to, fun, docstring ) ;
396  // }
397 
398 
399  class CppClass : public S4{
400  public:
402  CppClass( Module* p, class_Base* clazz, std::string& ) ;
403  CppClass( SEXP x) ;
404  CppClass( const CppClass& ) ;
405  CppClass& operator=( const CppClass& ) ;
406 
407  } ;
408 
409  class CppObject : public S4{
410  public:
412  CppObject( Module* p, class_Base*, SEXP xp ) ;
413  CppObject( const CppObject& ) ;
414  CppObject& operator=( const CppObject& ) ;
415 
416  } ;
417 
419  public:
420  FunctionProxy( DL_FUNC p_fun_ ): p_fun(p_fun_){}
421 
422  template <typename T> operator T() const { return (T)p_fun ; }
423 
424  private:
425  DL_FUNC p_fun ;
426  } ;
427 
428  FunctionProxy GetCppCallable( const std::string& pkg, const std::string& mod, const std::string& fun) ;
429 }
430 
431 #define RCPP_MODULE_BOOT(name) _rcpp_module_boot_##name
432 
433 #define RCPP_MODULE(name) \
434  void _rcpp_module_##name##_init() ; \
435  static Rcpp::Module _rcpp_module_##name( # name ) ; \
436  extern "C" SEXP _rcpp_module_boot_##name(){ \
437  ::setCurrentScope( & _rcpp_module_##name ) ; \
438  _rcpp_module_##name##_init( ) ; \
439  Rcpp::XPtr<Rcpp::Module> mod_xp(& _rcpp_module_##name , false); \
440  ::setCurrentScope( 0 ) ; \
441  return mod_xp ; \
442  } \
443  void _rcpp_module_##name##_init()
444 
445 // silly little dance to suppress a 'defined but not used variable' warning
446 #ifdef __GNUC__
447 #define VARIABLE_IS_NOT_USED __attribute__ ((unused))
448 #else
449 #define VARIABLE_IS_NOT_USED
450 #endif
451 
452 // static variable to hold Rf_install symbol to prevent it from being gc'ed
453 static VARIABLE_IS_NOT_USED SEXP moduleSym = NULL;
454 
455 // helper macro to cache the result of Rf_install("Module"): once
456 // it is allocated and in the symbol table it is safe from gc
457 #define GET_MODULE_SYM ( moduleSym == NULL ? moduleSym = Rf_install("Module") : moduleSym )
458 
459 // this macro is called by code wanting to load a module -- see RInside's rinside_module_sample0.cpp
460 #define LOAD_RCPP_MODULE(NAME) Rf_eval( Rf_lang2( GET_MODULE_SYM, _rcpp_module_boot_##NAME() ), R_GlobalEnv )
461 
462 #endif
463