21#ifndef Rcpp_Module_CLASS_h
22#define Rcpp_Module_CLASS_h
24 template <
typename Class>
36 typedef std::pair<const std::string,method_class*>
PAIR ;
51 typedef std::pair<const std::string,prop_class*>
PROP_PAIR ;
53 class_(
const char* name_,
const char* doc = 0) :
54 class_Base(name_, doc),
78 Module*
module = getCurrentScope() ;
79 if( module->has_class(name) ){
88 module->AddClass( name.c_str(), class_pointer ) ;
110 return constructor( docstring, valid ) ;
113#if defined(HAS_VARIADIC_TEMPLATES)
114 template <
typename... T>
115 self& constructor(
const char* docstring = 0, ValidConstructor valid = &yes_arity<
sizeof...(T)> ){
116 AddConstructor(
new Constructor<Class,T...> , valid, docstring ) ;
119 template <
typename... T>
120 self& factory( Class* (*fun)(T...),
const char* docstring = 0, ValidConstructor valid = &yes_arity<
sizeof...(T)> ){
121 AddFactory(
new Factory<Class,T...>(fun) , valid, docstring ) ;
125 #include <Rcpp/module/Module_generated_class_constructor.h>
126 #include <Rcpp/module/Module_generated_class_factory.h>
139 for(
size_t i=0; i<n; i++ ){
141 bool ok = (p->valid)(args, nargs) ;
143 Class* ptr = p->ctor->get_new( args, nargs ) ;
144 return XP( ptr,
true ) ;
150 for(
size_t i=0; i<n; i++){
152 bool ok = (pfact->valid)(args, nargs) ;
154 Class* ptr = pfact->fact->get_new( args, nargs ) ;
155 return XP( ptr,
true ) ;
159 throw std::range_error(
"no valid constructor available for the argument list" ) ;
166 for(
size_t i=0; i<n; i++ ){
168 if( p->nargs() == 0 )
return true ;
172 for(
size_t i=0; i<n; i++ ){
174 if( pfact->nargs() == 0 )
return true ;
179 SEXP
invoke( SEXP method_xp, SEXP
object, SEXP *args,
int nargs ){
183 typename vec_signed_method::iterator it = mets->begin() ;
184 size_t n = mets->size() ;
187 for(
size_t i=0; i<n; i++, ++it ){
188 if( ( (*it)->valid )( args, nargs) ){
195 throw std::range_error(
"could not find valid method" ) ;
198 m->operator()(
XP(
object), args );
206 SEXP
invoke_void( SEXP method_xp, SEXP
object, SEXP *args,
int nargs ){
210 typename vec_signed_method::iterator it = mets->begin() ;
211 size_t n = mets->size() ;
214 for(
size_t i=0; i<n; i++, ++it ){
215 if( ( (*it)->valid )( args, nargs) ){
222 throw std::range_error(
"could not find valid method" ) ;
224 m->operator()(
XP(
object), args );
232 typename vec_signed_method::iterator it = mets->begin() ;
233 size_t n = mets->size() ;
236 for(
size_t i=0; i<n; i++, ++it ){
237 if( ( (*it)->valid )( args, nargs) ){
244 throw std::range_error(
"could not find valid method" ) ;
246 return m->operator()(
XP(
object), args ) ;
252 RCPP_DEBUG_MODULE_1(
"AddMethod( %s, method_class* m, ValidMethod valid = &yes, const char* docstring = 0", name_ )
254 typename map_vec_signed_method::iterator it = ptr->
vec_methods.find( name_ ) ;
259 if( *name_ ==
'[' ) ptr->
specials++ ;
268#if defined(HAS_VARIADIC_TEMPLATES)
269 template <
typename RESULT_TYPE,
typename... T>
270 self& method(
const char* name_, RESULT_TYPE (Class::*fun)(T...),
271 const char* docstring = 0, ValidMethod valid = &yes_arity<sizeof...(T)>) {
272 AddMethod( name_,
new CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
275 template <
typename RESULT_TYPE,
typename... T>
276 self& method(
const char* name_, RESULT_TYPE (Class::*fun)(T...) const,
277 const char* docstring = 0,
ValidMethod valid = &yes_arity<sizeof...(T)>) {
278 AddMethod( name_,
new const_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
281 template <
typename RESULT_TYPE,
typename... T>
282 self& nonconst_method(
const char* name_, RESULT_TYPE (Class::*fun)(T...),
283 const char* docstring = 0,
ValidMethod valid = &yes_arity<sizeof...(T)>) {
284 AddMethod( name_,
new CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
287 template <
typename RESULT_TYPE,
typename... T>
288 self& const_method(
const char* name_, RESULT_TYPE (Class::*fun)(T...) const,
289 const char* docstring = 0,
ValidMethod valid = &yes_arity<sizeof...(T)>) {
290 AddMethod( name_,
new const_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
293 template <
typename RESULT_TYPE,
typename... T>
294 self& method(
const char* name_, RESULT_TYPE (*fun)(Class*, T...),
295 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
296 AddMethod( name_,
new Pointer_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
299 template <
typename RESULT_TYPE,
typename... T>
300 self& const_method(
const char* name_, RESULT_TYPE (*fun)(
const Class*, T...),
301 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
302 AddMethod( name_,
new Const_Pointer_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
306 #include <Rcpp/module/Module_generated_method.h>
307 #include <Rcpp/module/Module_generated_Pointer_method.h>
317 typename PROPERTY_MAP::iterator it =
properties.find( p ) ;
318 if( it ==
properties.end() )
throw std::range_error(
"no such property" ) ;
319 return it->second->is_readonly() ;
322 typename PROPERTY_MAP::iterator it =
properties.find( p ) ;
323 if( it ==
properties.end() )
throw std::range_error(
"no such property" ) ;
324 return it->second->get_class() ;
330 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
331 for(
size_t i=0; i<s; i++, ++it){
332 n += (it->second)->size() ;
337 for(
size_t i=0; i<s; i++, ++it){
338 n = (it->second)->size() ;
339 std::string name = it->first ;
340 for(
size_t j=0; j<n; j++, k++){
350 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
351 for(
size_t i=0; i<s; i++, ++it){
352 n += (it->second)->size() ;
358 for(
size_t i=0; i<s; i++, ++it){
359 n = (it->second)->size() ;
360 std::string name = it->first ;
361 typename vec_signed_method::iterator m_it = (it->second)->begin() ;
362 for(
size_t j=0; j<n; j++, k++, ++m_it){
364 res[k] = (*m_it)->nargs() ;
367 res.
names( ) = mnames ;
374 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
375 for(
size_t i=0; i<s; i++, ++it){
376 n += (it->second)->size() ;
382 for(
size_t i=0; i<s; i++, ++it){
383 n = (it->second)->size() ;
384 std::string name = it->first ;
385 typename vec_signed_method::iterator m_it = (it->second)->begin() ;
386 for(
size_t j=0; j<n; j++, k++, ++m_it){
388 res[k] = (*m_it)->is_void() ;
391 res.
names( ) = mnames ;
399 typename PROPERTY_MAP::iterator it =
properties.begin( ) ;
400 for(
size_t i=0; i<n; i++, ++it){
410 typename PROPERTY_MAP::iterator it =
properties.begin( ) ;
411 for(
size_t i=0; i<n; i++, ++it){
412 pnames[i] = it->first ;
413 out[i] = it->second->get_class() ;
415 out.
names() = pnames ;
423 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
428 if( buffer[0] ==
'[' ) continue ;
439 for( ; i<ntotal; i++, ++prop_it){
440 out[i] = prop_it->first ;
448 return prop->get(
XP(
object) );
455 return prop->set(
XP(
object), value );
464 typename PROPERTY_MAP::iterator it =
properties.begin( ) ;
465 for(
size_t i=0; i<n; i++, ++it){
466 pnames[i] = it->first ;
467 out[i] = S4_field<Class>( it->second, class_xp ) ;
469 out.
names() = pnames ;
474 RCPP_DEBUG_MODULE(
"Rcpp::List getMethods( const XP_Class& class_xp, std::string& buffer" )
475 #if RCPP_DEBUG_LEVEL > 0
476 Rf_PrintValue( class_xp ) ;
481 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
483 for(
size_t i=0; i<n; i++, ++it){
484 mnames[i] = it->first ;
486 res[i] = S4_CppOverloadedMethods<Class>( v , class_xp, it->first.c_str(), buffer ) ;
488 res.
names() = mnames ;
495 typename vec_signed_constructor::iterator it =
constructors.begin( ) ;
496 for(
size_t i=0; i<n; i++, ++it){
497 out[i] = S4_CppConstructor<Class>( *it , class_xp, name, buffer ) ;
537 template <
typename PARENT>
540 typedef typename parent_class_::signed_method_class parent_signed_method_class ;
541 typedef typename parent_class_::method_class parent_method_class ;
544 parent_class_* parent_class_pointer =
reinterpret_cast< parent_class_*
> ( scope->get_class_pointer( parent ) );
547 typename parent_class_::map_vec_signed_method::iterator parent_vec_methods_iterator = parent_class_pointer->vec_methods.begin() ;
548 typename parent_class_::map_vec_signed_method::iterator parent_vec_methods_end = parent_class_pointer->vec_methods.end() ;
549 std::string method_name ;
550 for( ; parent_vec_methods_iterator != parent_vec_methods_end; parent_vec_methods_iterator++){
551 method_name = parent_vec_methods_iterator->first ;
553 typedef typename parent_class_::vec_signed_method parent_vec_signed_method ;
554 parent_vec_signed_method* p_methods = parent_vec_methods_iterator->second ;
555 typename parent_vec_signed_method::iterator methods_it = p_methods->begin() ;
556 typename parent_vec_signed_method::iterator methods_end = p_methods->end() ;
558 for( ; methods_it != methods_end; methods_it++){
559 parent_signed_method_class* signed_method = *methods_it ;
560 parent_method_class* parent_method = signed_method->method ;
562 CppMethod<Class>* method =
new CppInheritedMethod<Class,PARENT>( parent_method ) ;
564 AddMethod( method_name.c_str(), method, signed_method->valid , signed_method->docstring.c_str() ) ;
570 typedef typename parent_class_::PROPERTY_MAP parent_PROPERTY_MAP ;
571 typedef typename parent_PROPERTY_MAP::iterator parent_PROPERTY_MAP_iterator ;
573 parent_PROPERTY_MAP_iterator parent_property_it = parent_class_pointer->properties.begin() ;
574 parent_PROPERTY_MAP_iterator parent_property_end = parent_class_pointer->properties.end() ;
575 for( ; parent_property_it != parent_property_end; parent_property_it++){
577 parent_property_it->first.c_str(),
578 new CppInheritedProperty<Class,PARENT>( parent_property_it->second )
582 std::string buffer(
"Rcpp_" ) ; buffer += parent ;
void SetFinalizer(finalizer_class *f)
SignedMethod< Class > signed_method_class
std::map< std::string, prop_class * > PROPERTY_MAP
self & AddConstructor(constructor_class *ctor, ValidConstructor valid, const char *docstring=0)
vec_signed_constructor constructors
SEXP invoke_notvoid(SEXP method_xp, SEXP object, SEXP *args, int nargs)
SignedFactory< Class > signed_factory_class
CppFinalizer< Class > finalizer_class
Factory_Base< Class > factory_class
bool has_method(const std::string &m)
std::map< std::string, method_class * > METHOD_MAP
Rcpp::List property_classes()
std::map< std::string, vec_signed_method * > map_vec_signed_method
void setProperty(SEXP field_xp, SEXP object, SEXP value)
std::vector< signed_method_class * > vec_signed_method
self & finalizer(void(*f)(Class *))
Rcpp::List getConstructors(const XP_Class &class_xp, std::string &buffer)
CppMethod< Class > method_class
virtual void run_finalizer(SEXP object)
self & default_constructor(const char *docstring=0, ValidConstructor valid=&yes_arity< 0 >)
Rcpp::List fields(const XP_Class &class_xp)
class_(const char *name_, const char *doc=0)
std::pair< const std::string, method_class * > PAIR
std::string property_class(const std::string &p)
std::pair< std::string, vec_signed_method * > vec_signed_method_pair
Constructor_Base< Class > constructor_class
self & AddFactory(factory_class *fact, ValidConstructor valid, const char *docstring=0)
Rcpp::CharacterVector property_names()
self & derives(const char *parent)
finalizer_class * finalizer_pointer
SEXP invoke(SEXP method_xp, SEXP object, SEXP *args, int nargs)
std::string typeinfo_name
Rcpp::CharacterVector complete()
Rcpp::LogicalVector methods_voidness()
Rcpp::CharacterVector method_names()
vec_signed_factory factories
SEXP newInstance(SEXP *args, int nargs)
SEXP invoke_void(SEXP method_xp, SEXP object, SEXP *args, int nargs)
std::string get_typeinfo_name()
Rcpp::List getMethods(const XP_Class &class_xp, std::string &buffer)
std::pair< const std::string, prop_class * > PROP_PAIR
self & AddProperty(const char *name_, prop_class *p)
SEXP getProperty(SEXP field_xp, SEXP object)
bool property_is_readonly(const std::string &p)
bool has_property(const std::string &m)
CppProperty< Class > prop_class
map_vec_signed_method vec_methods
self & AddMethod(const char *name_, method_class *m, ValidMethod valid=&yes, const char *docstring=0)
SignedConstructor< Class > signed_constructor_class
std::vector< signed_constructor_class * > vec_signed_constructor
std::vector< signed_factory_class * > vec_signed_factory
Rcpp::IntegerVector methods_arity()
bool has_default_constructor()
#define RCPP_DEBUG_MODULE_1(fmt, MSG)
#define RCPP_DEBUG_MODULE(MSG)
#define RCPP_DEBUG_MODULE_2(fmt, M1, M2)
#define DEMANGLE(__TYPE__)
bool(* ValidMethod)(SEXP *, int)
attribute_hidden Rcpp::Module * getCurrentScope()