|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 // 00003 // Module.h: Rcpp R/C++ interface class library -- Rcpp modules 00004 // 00005 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 00006 // 00007 // This file is part of Rcpp. 00008 // 00009 // Rcpp is free software: you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // Rcpp is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #ifndef Rcpp_Module_h 00023 #define Rcpp_Module_h 00024 00025 #include <Rcpp/config.h> 00026 00027 namespace Rcpp{ 00028 00029 class CppClass ; 00030 class CppObject ; 00031 00032 template <typename T> 00033 class result { 00034 public: 00035 result( T* ptr_ ) : ptr(ptr_){} 00036 operator T*(){ return ptr ; } 00037 private: 00038 T* ptr; 00039 } ; 00040 00041 namespace internal { 00042 template <typename Class> 00043 SEXP make_new_object( Class* ptr ){ 00044 Rcpp::XPtr<Class> xp( ptr, true ) ; 00045 Function maker = Environment::Rcpp_namespace()[ "cpp_object_maker"] ; 00046 return maker( typeid(Class).name() , xp ) ; 00047 } 00048 } 00049 00050 class CppFunction { 00051 public: 00052 CppFunction(const char* doc = 0) : docstring( doc == 0 ? "" : doc) {} 00053 virtual SEXP operator()(SEXP*) { 00054 return R_NilValue ; 00055 } 00056 virtual ~CppFunction(){} ; 00057 virtual int nargs(){ return 0 ; } 00058 virtual bool is_void(){ return false ; } 00059 virtual void signature(std::string&, const char* ){} 00060 virtual SEXP get_formals(){ return R_NilValue; } 00061 00062 std::string docstring ; 00063 }; 00064 00065 #include <Rcpp/module/Module_generated_get_return_type.h> 00066 #include <Rcpp/module/Module_generated_get_signature.h> 00067 00068 // templates CppFunction0, ..., CppFunction65 00069 #include <Rcpp/module/Module_generated_CppFunction.h> 00070 00071 class class_Base { 00072 public: 00073 class_Base() : name(), docstring() {} ; 00074 class_Base(const char* name_, const char* doc) : 00075 name(name_), docstring( doc == 0 ? "" : doc ){} ; 00076 00077 virtual Rcpp::List fields(SEXP){ return Rcpp::List(0); } 00078 virtual Rcpp::List getMethods(SEXP, std::string&){ return Rcpp::List(0); } 00079 virtual Rcpp::List getConstructors(SEXP, std::string&){ return Rcpp::List(0); } 00080 00081 virtual void run_finalizer(SEXP){ } 00082 00083 virtual bool has_default_constructor(){ return false ; } 00084 virtual bool has_method( const std::string& ){ 00085 return false ; 00086 } 00087 virtual bool has_property( const std::string& ) { 00088 return false ; 00089 } 00090 virtual SEXP newInstance(SEXP *, int){ 00091 return R_NilValue; 00092 } 00093 virtual SEXP invoke( SEXP, SEXP, SEXP *, int ){ 00094 return R_NilValue ; 00095 } 00096 virtual SEXP invoke_void( SEXP, SEXP, SEXP *, int ){ 00097 return R_NilValue ; 00098 } 00099 virtual SEXP invoke_notvoid( SEXP, SEXP, SEXP *, int ){ 00100 return R_NilValue ; 00101 } 00102 00103 virtual Rcpp::CharacterVector method_names(){ return Rcpp::CharacterVector(0) ; } 00104 virtual Rcpp::CharacterVector property_names(){ return Rcpp::CharacterVector(0) ; } 00105 virtual bool property_is_readonly(const std::string& ) { return false ; } 00106 virtual std::string property_class(const std::string& ) { return "" ; } 00107 virtual Rcpp::IntegerVector methods_arity(){ return Rcpp::IntegerVector(0) ; } 00108 virtual Rcpp::LogicalVector methods_voidness(){ return Rcpp::LogicalVector(0); } 00109 virtual Rcpp::List property_classes(){ return Rcpp::List(0); } 00110 00111 virtual Rcpp::CharacterVector complete(){ return Rcpp::CharacterVector(0) ; } 00112 virtual ~class_Base(){} 00113 00114 virtual SEXP getProperty( SEXP, SEXP ) { 00115 throw std::range_error( "cannot retrieve property" ) ; 00116 } 00117 virtual void setProperty( SEXP, SEXP, SEXP) { 00118 throw std::range_error( "cannot set property" ) ; 00119 } 00120 virtual std::string get_typeinfo_name(){ return "" ; } 00121 00122 std::string name ; 00123 std::string docstring ; 00124 } ; 00125 00126 class Module { 00127 public: 00128 typedef std::map<std::string,CppFunction*> MAP ; 00129 typedef std::pair<const std::string,CppFunction*> FUNCTION_PAIR ; 00130 00131 typedef std::map<std::string,class_Base*> CLASS_MAP ; 00132 typedef std::pair<const std::string,class_Base*> CLASS_PAIR ; 00133 00134 Module() ; 00135 Module(const char* name_) ; 00136 00137 SEXP invoke( const std::string& /* name */, SEXP* /* args */, int /* nargs */ ) ; 00138 00139 Rcpp::IntegerVector functions_arity() ; 00140 Rcpp::CharacterVector functions_names() ; 00141 00142 Rcpp::CharacterVector class_names() ; 00143 Rcpp::List classes_info() ; 00144 Rcpp::CharacterVector complete() ; 00145 SEXP get_function_ptr( const std::string& ) ; 00146 00147 inline void Add( const char* name_ , CppFunction* ptr){ 00148 functions.insert( FUNCTION_PAIR( name_ , ptr ) ) ; 00149 } 00150 00151 inline void AddClass(const char* name_ , class_Base* cptr){ 00152 classes.insert( CLASS_PAIR( name_ , cptr ) ) ; 00153 } 00154 00155 inline bool has_function( const std::string& m){ 00156 return functions.find(m) != functions.end() ; 00157 } 00158 00159 inline bool has_class( const std::string& m){ 00160 return classes.find(m) != classes.end() ; 00161 } 00162 00163 Rcpp::CppClass get_class(const std::string& ) ; 00164 00165 std::string name ; 00166 00167 private: 00168 MAP functions ; 00169 CLASS_MAP classes ; 00170 00171 }; 00172 00173 } 00174 extern "C" Rcpp::Module* getCurrentScope() ; 00175 extern "C" void setCurrentScope( Rcpp::Module* ) ; 00176 00177 namespace Rcpp{ 00178 00179 template <typename Class> 00180 class CppMethod { 00181 public: 00182 typedef Rcpp::XPtr<Class> XP ; 00183 00184 CppMethod() {} 00185 virtual SEXP operator()(Class* object, SEXP* args) { return R_NilValue ; } 00186 virtual ~CppMethod(){} 00187 virtual int nargs(){ return 0 ; } 00188 virtual bool is_void(){ return false ; } 00189 virtual bool is_const(){ return false ; } 00190 virtual void signature(std::string& s, const char* name ){ s = name ; } 00191 } ; 00192 00193 #include <Rcpp/module/Module_generated_ctor_signature.h> 00194 #include <Rcpp/module/Module_generated_Constructor.h> 00195 #include <Rcpp/module/Module_generated_class_signature.h> 00196 00197 typedef bool (*ValidConstructor)(SEXP*,int) ; 00198 typedef bool (*ValidMethod)(SEXP*,int) ; 00199 00200 template <typename Class> 00201 class SignedConstructor { 00202 public: 00203 00204 SignedConstructor( 00205 Constructor_Base<Class>* ctor_, 00206 ValidConstructor valid_, 00207 const char* doc 00208 ) : ctor(ctor_), valid(valid_), docstring(doc == 0 ? "" : doc){} 00209 00210 Constructor_Base<Class>* ctor ; 00211 ValidConstructor valid ; 00212 std::string docstring ; 00213 00214 inline int nargs(){ return ctor->nargs() ; } 00215 inline void signature(std::string& buffer, const std::string& class_name){ 00216 ctor->signature(buffer, class_name) ; 00217 } 00218 } ; 00219 00220 template <typename Class> 00221 class SignedMethod { 00222 public: 00223 typedef CppMethod<Class> METHOD ; 00224 SignedMethod( METHOD* m, ValidMethod valid_, const char* doc ) : method(m), valid(valid_), docstring(doc == 0 ? "" : doc) {} 00225 00226 METHOD* method ; 00227 ValidMethod valid ; 00228 std::string docstring ; 00229 00230 inline int nargs(){ return method->nargs() ; } 00231 inline bool is_void(){ return method->is_void() ; } 00232 inline bool is_const(){ return method->is_const() ; } 00233 inline void signature(std::string& s, const char* name){ 00234 method->signature(s, name); 00235 } 00236 00237 } ; 00238 00239 template <typename Class> 00240 class S4_CppConstructor : public Rcpp::Reference { 00241 public: 00242 S4_CppConstructor( SignedConstructor<Class>* m, SEXP class_xp, const std::string& class_name, std::string& buffer ) : Reference( "C++Constructor" ){ 00243 field( "pointer" ) = Rcpp::XPtr< SignedConstructor<Class> >( m, false ) ; 00244 field( "class_pointer" ) = class_xp ; 00245 field( "nargs" ) = m->nargs() ; 00246 m->signature( buffer, class_name ) ; 00247 field( "signature" ) = buffer ; 00248 field( "docstring" ) = m->docstring ; 00249 } 00250 } ; 00251 00252 template <typename Class> 00253 class S4_CppOverloadedMethods : public Rcpp::Reference { 00254 public: 00255 typedef SignedMethod<Class> signed_method_class ; 00256 typedef std::vector<signed_method_class*> vec_signed_method ; 00257 00258 S4_CppOverloadedMethods( vec_signed_method* m, SEXP class_xp, const char* name, std::string& buffer ) : Reference( "C++OverloadedMethods" ){ 00259 int n = m->size() ; 00260 Rcpp::LogicalVector voidness(n), constness(n) ; 00261 Rcpp::CharacterVector docstrings(n), signatures(n) ; 00262 signed_method_class* met ; 00263 for( int i=0; i<n; i++){ 00264 met = m->at(i) ; 00265 voidness[i] = met->is_void() ; 00266 constness[i] = met->is_const() ; 00267 docstrings[i] = met->docstring ; 00268 met->signature(buffer, name) ; 00269 signatures[i] = buffer ; 00270 } 00271 00272 field( "pointer" ) = Rcpp::XPtr< vec_signed_method >( m, false ) ; 00273 field( "class_pointer" ) = class_xp ; 00274 field( "size" ) = n ; 00275 field( "void" ) = voidness ; 00276 field( "const" ) = constness ; 00277 field( "docstrings" ) = docstrings ; 00278 field( "signatures" ) = signatures ; 00279 } 00280 } ; 00281 00282 #include <Rcpp/module/Module_generated_CppMethod.h> 00283 #include <Rcpp/module/Module_generated_Pointer_CppMethod.h> 00284 00285 template <typename Class> 00286 class CppProperty { 00287 public: 00288 typedef Rcpp::XPtr<Class> XP ; 00289 00290 CppProperty(const char* doc = 0) : docstring( doc == 0 ? "" : doc ) {} ; 00291 virtual SEXP get(Class* ) { throw std::range_error("cannot retrieve property"); } 00292 virtual void set(Class*, SEXP) { throw std::range_error("cannot set property"); } 00293 virtual bool is_readonly(){ return false; } 00294 virtual std::string get_class(){ return ""; } 00295 00296 std::string docstring ; 00297 } ; 00298 00299 template <typename Class> 00300 class CppFinalizer{ 00301 public: 00302 CppFinalizer(){} ; 00303 virtual void run(Class* ){} ; 00304 } ; 00305 00306 template <typename Class> 00307 class FunctionFinalizer : public CppFinalizer<Class> { 00308 public: 00309 typedef void (*Pointer)(Class*) ; 00310 FunctionFinalizer( Pointer p ) : finalizer(p){} ; 00311 00312 virtual void run(Class* object){ 00313 finalizer( object ) ; 00314 } 00315 00316 private: 00317 Pointer finalizer ; 00318 } ; 00319 00320 template <typename Class> 00321 class S4_field : public Rcpp::Reference { 00322 public: 00323 S4_field( CppProperty<Class>* p, SEXP class_xp ) : Reference( "C++Field" ){ 00324 field( "read_only" ) = p->is_readonly() ; 00325 field( "cpp_class" ) = p->get_class(); 00326 field( "pointer" ) = Rcpp::XPtr< CppProperty<Class> >( p, false ) ; 00327 field( "class_pointer" ) = class_xp ; 00328 field( "docstring" ) = p->docstring ; 00329 } 00330 } ; 00331 00332 #include <Rcpp/module/Module_Property.h> 00333 00334 template <typename Class> 00335 class class_ : public class_Base { 00336 public: 00337 typedef class_<Class> self ; 00338 typedef CppMethod<Class> method_class ; 00339 00340 typedef SignedMethod<Class> signed_method_class ; 00341 typedef std::vector<signed_method_class*> vec_signed_method ; 00342 typedef std::map<std::string,vec_signed_method*> map_vec_signed_method ; 00343 typedef std::pair<std::string,vec_signed_method*> vec_signed_method_pair ; 00344 00345 typedef std::map<std::string,method_class*> METHOD_MAP ; 00346 typedef std::pair<const std::string,method_class*> PAIR ; 00347 00348 typedef Rcpp::XPtr<Class> XP ; 00349 typedef CppFinalizer<Class> finalizer_class ; 00350 00351 typedef Constructor_Base<Class> constructor_class ; 00352 typedef SignedConstructor<Class> signed_constructor_class ; 00353 typedef std::vector<signed_constructor_class*> vec_signed_constructor ; 00354 00355 typedef CppProperty<Class> prop_class ; 00356 typedef std::map<std::string,prop_class*> PROPERTY_MAP ; 00357 typedef std::pair<const std::string,prop_class*> PROP_PAIR ; 00358 00359 class_( const char* name_, const char* doc = 0) : 00360 class_Base(name_, 0), 00361 vec_methods(), 00362 properties(), 00363 finalizer_pointer(0), 00364 specials(0), 00365 constructors(), 00366 class_pointer(0), 00367 typeinfo_name("") 00368 { 00369 Rcpp::Module* module = getCurrentScope() ; 00370 if( ! module->has_class(name_) ){ 00371 class_pointer = new self ; 00372 class_pointer->name = name_ ; 00373 class_pointer->docstring = std::string( doc == 0 ? "" : doc ); 00374 class_pointer->finalizer_pointer = new finalizer_class ; 00375 class_pointer->typeinfo_name = typeid(Class).name() ; 00376 module->AddClass( name_, class_pointer ) ; 00377 } 00378 } 00379 00380 ~class_(){} 00381 00382 00383 self& AddConstructor( constructor_class* ctor, ValidConstructor valid, const char* docstring = 0 ){ 00384 class_pointer->constructors.push_back( new signed_constructor_class( ctor, valid, docstring ) ); 00385 return *this ; 00386 } 00387 00388 self& default_constructor( const char* docstring= 0, ValidConstructor valid = &yes_arity<0> ){ 00389 return constructor( docstring, valid ) ; 00390 } 00391 00392 #include <Rcpp/module/Module_generated_class_constructor.h> 00393 00394 public: 00395 00396 std::string get_typeinfo_name(){ 00397 return typeinfo_name ; 00398 } 00399 00400 SEXP newInstance( SEXP* args, int nargs ){ 00401 BEGIN_RCPP 00402 signed_constructor_class* p ; 00403 int n = constructors.size() ; 00404 for( int i=0; i<n; i++ ){ 00405 p = constructors[i]; 00406 bool ok = (p->valid)(args, nargs) ; 00407 if( ok ){ 00408 Class* ptr = p->ctor->get_new( args, nargs ) ; 00409 return XP( ptr, true ) ; 00410 } 00411 } 00412 throw std::range_error( "no valid constructor available for the argument list" ) ; 00413 END_RCPP 00414 } 00415 00416 bool has_default_constructor(){ 00417 int n = constructors.size() ; 00418 signed_constructor_class* p ; 00419 for( int i=0; i<n; i++ ){ 00420 p = constructors[i]; 00421 if( p->nargs() == 0 ) return true ; 00422 } 00423 return false ; 00424 } 00425 00426 SEXP invoke( SEXP method_xp, SEXP object, SEXP *args, int nargs ){ 00427 BEGIN_RCPP 00428 00429 vec_signed_method* mets = reinterpret_cast< vec_signed_method* >( EXTPTR_PTR( method_xp ) ) ; 00430 typename vec_signed_method::iterator it = mets->begin() ; 00431 int n = mets->size() ; 00432 method_class* m = 0 ; 00433 bool ok = false ; 00434 for( int i=0; i<n; i++, ++it ){ 00435 if( ( (*it)->valid )( args, nargs) ){ 00436 m = (*it)->method ; 00437 ok = true ; 00438 break ; 00439 } 00440 } 00441 if( !ok ){ 00442 throw std::range_error( "could not find valid method" ) ; 00443 } 00444 if( m->is_void() ){ 00445 m->operator()( XP(object), args ); 00446 return Rcpp::List::create( true ) ; 00447 } else { 00448 return Rcpp::List::create( false, m->operator()( XP(object), args ) ) ; 00449 } 00450 END_RCPP 00451 } 00452 00453 SEXP invoke_void( SEXP method_xp, SEXP object, SEXP *args, int nargs ){ 00454 BEGIN_RCPP 00455 00456 vec_signed_method* mets = reinterpret_cast< vec_signed_method* >( EXTPTR_PTR( method_xp ) ) ; 00457 typename vec_signed_method::iterator it = mets->begin() ; 00458 int n = mets->size() ; 00459 method_class* m = 0 ; 00460 bool ok = false ; 00461 for( int i=0; i<n; i++, ++it ){ 00462 if( ( (*it)->valid )( args, nargs) ){ 00463 m = (*it)->method ; 00464 ok = true ; 00465 break ; 00466 } 00467 } 00468 if( !ok ){ 00469 throw std::range_error( "could not find valid method" ) ; 00470 } 00471 m->operator()( XP(object), args ); 00472 END_RCPP 00473 } 00474 00475 SEXP invoke_notvoid( SEXP method_xp, SEXP object, SEXP *args, int nargs ){ 00476 BEGIN_RCPP 00477 00478 vec_signed_method* mets = reinterpret_cast< vec_signed_method* >( EXTPTR_PTR( method_xp ) ) ; 00479 typename vec_signed_method::iterator it = mets->begin() ; 00480 int n = mets->size() ; 00481 method_class* m = 0 ; 00482 bool ok = false ; 00483 for( int i=0; i<n; i++, ++it ){ 00484 if( ( (*it)->valid )( args, nargs) ){ 00485 m = (*it)->method ; 00486 ok = true ; 00487 break ; 00488 } 00489 } 00490 if( !ok ){ 00491 throw std::range_error( "could not find valid method" ) ; 00492 } 00493 return m->operator()( XP(object), args ) ; 00494 END_RCPP 00495 } 00496 00497 00498 self& AddMethod( const char* name_, method_class* m, ValidMethod valid = &yes, const char* docstring = 0){ 00499 typename map_vec_signed_method::iterator it = class_pointer->vec_methods.find( name_ ) ; 00500 if( it == class_pointer->vec_methods.end() ){ 00501 it = class_pointer->vec_methods.insert( vec_signed_method_pair( name_, new vec_signed_method() ) ).first ; 00502 } 00503 (it->second)->push_back( new signed_method_class(m, valid, docstring ) ) ; 00504 if( *name_ == '[' ) class_pointer->specials++ ; 00505 return *this ; 00506 } 00507 00508 self& AddProperty( const char* name_, prop_class* p){ 00509 class_pointer->properties.insert( PROP_PAIR( name_, p ) ) ; 00510 return *this ; 00511 } 00512 00513 #include <Rcpp/module/Module_generated_method.h> 00514 #include <Rcpp/module/Module_generated_Pointer_method.h> 00515 00516 bool has_method( const std::string& m){ 00517 return vec_methods.find(m) != vec_methods.end() ; 00518 } 00519 bool has_property( const std::string& m){ 00520 return properties.find(m) != properties.end() ; 00521 } 00522 bool property_is_readonly( const std::string& p) { 00523 typename PROPERTY_MAP::iterator it = properties.find( p ) ; 00524 if( it == properties.end() ) throw std::range_error( "no such property" ) ; 00525 return it->second->is_readonly() ; 00526 } 00527 std::string property_class(const std::string& p) { 00528 typename PROPERTY_MAP::iterator it = properties.find( p ) ; 00529 if( it == properties.end() ) throw std::range_error( "no such property" ) ; 00530 return it->second->get_class() ; 00531 } 00532 00533 Rcpp::CharacterVector method_names(){ 00534 int n = 0 ; 00535 int s = vec_methods.size() ; 00536 typename map_vec_signed_method::iterator it = vec_methods.begin( ) ; 00537 for( int i=0; i<s; i++, ++it){ 00538 n += (it->second)->size() ; 00539 } 00540 Rcpp::CharacterVector out(n) ; 00541 it = vec_methods.begin() ; 00542 int k = 0 ; 00543 for( int i=0; i<s; i++, ++it){ 00544 n = (it->second)->size() ; 00545 std::string name = it->first ; 00546 for( int j=0; j<n; j++, k++){ 00547 out[k] = name ; 00548 } 00549 } 00550 return out ; 00551 } 00552 00553 Rcpp::IntegerVector methods_arity(){ 00554 int n = 0 ; 00555 int s = vec_methods.size() ; 00556 typename map_vec_signed_method::iterator it = vec_methods.begin( ) ; 00557 for( int i=0; i<s; i++, ++it){ 00558 n += (it->second)->size() ; 00559 } 00560 Rcpp::CharacterVector mnames(n) ; 00561 Rcpp::IntegerVector res(n) ; 00562 it = vec_methods.begin() ; 00563 int k = 0 ; 00564 for( int i=0; i<s; i++, ++it){ 00565 n = (it->second)->size() ; 00566 std::string name = it->first ; 00567 typename vec_signed_method::iterator m_it = (it->second)->begin() ; 00568 for( int j=0; j<n; j++, k++, ++m_it){ 00569 mnames[k] = name ; 00570 res[k] = (*m_it)->nargs() ; 00571 } 00572 } 00573 res.names( ) = mnames ; 00574 return res ; 00575 } 00576 00577 Rcpp::LogicalVector methods_voidness(){ 00578 int n = 0 ; 00579 int s = vec_methods.size() ; 00580 typename map_vec_signed_method::iterator it = vec_methods.begin( ) ; 00581 for( int i=0; i<s; i++, ++it){ 00582 n += (it->second)->size() ; 00583 } 00584 Rcpp::CharacterVector mnames(n) ; 00585 Rcpp::LogicalVector res(n) ; 00586 it = vec_methods.begin() ; 00587 int k = 0 ; 00588 for( int i=0; i<s; i++, ++it){ 00589 n = (it->second)->size() ; 00590 std::string name = it->first ; 00591 typename vec_signed_method::iterator m_it = (it->second)->begin() ; 00592 for( int j=0; j<n; j++, k++, ++m_it){ 00593 mnames[k] = name ; 00594 res[k] = (*m_it)->is_void() ; 00595 } 00596 } 00597 res.names( ) = mnames ; 00598 return res ; 00599 } 00600 00601 00602 Rcpp::CharacterVector property_names(){ 00603 int n = properties.size() ; 00604 Rcpp::CharacterVector out(n) ; 00605 typename PROPERTY_MAP::iterator it = properties.begin( ) ; 00606 for( int i=0; i<n; i++, ++it){ 00607 out[i] = it->first ; 00608 } 00609 return out ; 00610 } 00611 00612 Rcpp::List property_classes(){ 00613 int n = properties.size() ; 00614 Rcpp::CharacterVector pnames(n) ; 00615 Rcpp::List out(n) ; 00616 typename PROPERTY_MAP::iterator it = properties.begin( ) ; 00617 for( int i=0; i<n; i++, ++it){ 00618 pnames[i] = it->first ; 00619 out[i] = it->second->get_class() ; 00620 } 00621 out.names() = pnames ; 00622 return out ; 00623 } 00624 00625 Rcpp::CharacterVector complete(){ 00626 int n = vec_methods.size() - specials ; 00627 int ntotal = n + properties.size() ; 00628 Rcpp::CharacterVector out(ntotal) ; 00629 typename map_vec_signed_method::iterator it = vec_methods.begin( ) ; 00630 std::string buffer ; 00631 int i=0 ; 00632 for( ; i<n; ++it){ 00633 buffer = it->first ; 00634 if( buffer[0] == '[' ) continue ; 00635 // if( (it->second)->nargs() == 0){ 00636 // buffer += "() " ; 00637 // } else { 00638 // buffer += "( " ; 00639 // } 00640 buffer += "( " ; 00641 out[i] = buffer ; 00642 i++ ; 00643 } 00644 typename PROPERTY_MAP::iterator prop_it = properties.begin(); 00645 for( ; i<ntotal; i++, ++prop_it){ 00646 out[i] = prop_it->first ; 00647 } 00648 return out ; 00649 } 00650 00651 SEXP getProperty( SEXP field_xp , SEXP object) { 00652 BEGIN_RCPP 00653 prop_class* prop = reinterpret_cast< prop_class* >( EXTPTR_PTR( field_xp ) ) ; 00654 return prop->get( XP(object) ); 00655 END_RCPP 00656 } 00657 00658 void setProperty( SEXP field_xp, SEXP object, SEXP value) { 00659 BEGIN_RCPP 00660 prop_class* prop = reinterpret_cast< prop_class* >( EXTPTR_PTR( field_xp ) ) ; 00661 return prop->set( XP(object), value ); 00662 VOID_END_RCPP 00663 } 00664 00665 00666 Rcpp::List fields( SEXP class_xp ){ 00667 int n = properties.size() ; 00668 Rcpp::CharacterVector pnames(n) ; 00669 Rcpp::List out(n) ; 00670 typename PROPERTY_MAP::iterator it = properties.begin( ) ; 00671 for( int i=0; i<n; i++, ++it){ 00672 pnames[i] = it->first ; 00673 out[i] = S4_field<Class>( it->second, class_xp ) ; 00674 } 00675 out.names() = pnames ; 00676 return out ; 00677 } 00678 00679 Rcpp::List getMethods( SEXP class_xp, std::string& buffer){ 00680 int n = vec_methods.size() ; 00681 Rcpp::CharacterVector mnames(n) ; 00682 Rcpp::List res(n) ; 00683 typename map_vec_signed_method::iterator it = vec_methods.begin( ) ; 00684 vec_signed_method* v; 00685 for( int i=0; i<n; i++, ++it){ 00686 mnames[i] = it->first ; 00687 v = it->second ; 00688 res[i] = S4_CppOverloadedMethods<Class>( v , class_xp, it->first.c_str(), buffer ) ; 00689 } 00690 res.names() = mnames ; 00691 return res ; 00692 } 00693 00694 Rcpp::List getConstructors( SEXP class_xp, std::string& buffer){ 00695 int n = constructors.size() ; 00696 Rcpp::List out(n) ; 00697 typename vec_signed_constructor::iterator it = constructors.begin( ) ; 00698 for( int i=0; i<n; i++, ++it){ 00699 out[i] = S4_CppConstructor<Class>( *it , class_xp, name, buffer ) ; 00700 } 00701 return out ; 00702 } 00703 00704 #include <Rcpp/module/Module_Field.h> 00705 00706 #include <Rcpp/module/Module_Add_Property.h> 00707 00708 self& finalizer( void (*f)(Class*) ){ 00709 SetFinalizer( new FunctionFinalizer<Class>( f ) ) ; 00710 return *this ; 00711 } 00712 00713 virtual void run_finalizer( SEXP object ){ 00714 finalizer_pointer->run( XP(object) ) ; 00715 } 00716 00717 private: 00718 00719 void SetFinalizer( finalizer_class* f ){ 00720 if( class_pointer->finalizer_pointer ) delete class_pointer->finalizer ; 00721 class_pointer->finalizer_pointer = f ; 00722 } 00723 00724 map_vec_signed_method vec_methods ; 00725 PROPERTY_MAP properties ; 00726 00727 finalizer_class* finalizer_pointer ; 00728 int specials ; 00729 vec_signed_constructor constructors ; 00730 self* class_pointer ; 00731 std::string typeinfo_name ; 00732 00733 class_( ) : class_Base(), vec_methods(), properties(), specials(0) {}; 00734 00735 } ; 00736 00737 // function factories 00738 #include <Rcpp/module/Module_generated_function.h> 00739 00740 class CppClass : public S4{ 00741 public: 00742 typedef Rcpp::XPtr<Rcpp::Module> XP ; 00743 CppClass( Module* p, class_Base* clazz, std::string& ) ; 00744 CppClass( SEXP x) ; 00745 } ; 00746 00747 class CppObject : public S4{ 00748 public: 00749 typedef Rcpp::XPtr<Rcpp::Module> XP ; 00750 CppObject( Module* p, class_Base*, SEXP xp ) ; 00751 } ; 00752 00753 } 00754 00755 #define RCPP_MODULE_BOOT(name) _rcpp_module_boot_##name 00756 00757 #define RCPP_MODULE(name) \ 00758 void _rcpp_module_##name##_init() ; \ 00759 static Rcpp::Module _rcpp_module_##name( # name ) ; \ 00760 extern "C" SEXP _rcpp_module_boot_##name(){ \ 00761 ::setCurrentScope( & _rcpp_module_##name ) ; \ 00762 _rcpp_module_##name##_init( ) ; \ 00763 Rcpp::XPtr<Rcpp::Module> mod_xp(& _rcpp_module_##name , false); \ 00764 ::setCurrentScope( 0 ) ; \ 00765 return mod_xp ; \ 00766 } \ 00767 void _rcpp_module_##name##_init() 00768 00769 // silly little dance to suppress a 'defined but not used variable' warning 00770 #ifdef __GNUC__ 00771 #define VARIABLE_IS_NOT_USED __attribute__ ((unused)) 00772 #else 00773 #define VARIABLE_IS_NOT_USED 00774 #endif 00775 00776 // static variable to hold Rf_install symbol to prevent it from being gc'ed 00777 static VARIABLE_IS_NOT_USED SEXP moduleSym = NULL; 00778 00779 // helper macro to cache the result of Rf_install("Module"): once 00780 // it is allocated and in the symbol table it is safe from gc 00781 #define GET_MODULE_SYM ( moduleSym == NULL ? moduleSym = Rf_install("Module") : moduleSym ) 00782 00783 // this macro is called by code wanting to load a module -- see RInside's rinside_module_sample0.cpp 00784 #define LOAD_RCPP_MODULE(NAME) Rf_eval( Rf_lang2( GET_MODULE_SYM, _rcpp_module_boot_##NAME() ), R_GlobalEnv ) 00785 00786 #endif 00787