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),
79 if( module->has_class(name) ){
88 module->AddClass( name.c_str(), class_pointer ) ;
113 template <
typename... T>
114 self&
constructor(
const char* docstring = 0, ValidConstructor valid = &yes_arity<
sizeof...(T)> ){
115 AddConstructor(
new Constructor<Class,T...> , valid, docstring ) ;
118 template <
typename... T>
119 self&
factory( Class* (*fun)(T...),
const char* docstring = 0, ValidConstructor valid = &yes_arity<
sizeof...(T)> ){
120 AddFactory(
new Factory<Class,T...>(fun) , valid, docstring ) ;
134 for(
size_t i=0; i<n; i++ ){
136 bool ok = (p->valid)(args, nargs) ;
138 Class* ptr = p->ctor->get_new( args, nargs ) ;
139 return XP( ptr,
true ) ;
145 for(
size_t i=0; i<n; i++){
147 bool ok = (pfact->valid)(args, nargs) ;
149 Class* ptr = pfact->fact->get_new( args, nargs ) ;
150 return XP( ptr,
true ) ;
154 throw std::range_error(
"no valid constructor available for the argument list" ) ;
161 for(
size_t i=0; i<n; i++ ){
163 if( p->nargs() == 0 )
return true ;
167 for(
size_t i=0; i<n; i++ ){
169 if( pfact->nargs() == 0 )
return true ;
174 SEXP
invoke( SEXP method_xp, SEXP
object, SEXP *args,
int nargs ){
178 typename vec_signed_method::iterator it = mets->begin() ;
179 size_t n = mets->size() ;
182 for(
size_t i=0; i<n; i++, ++it ){
183 if( ( (*it)->valid )( args, nargs) ){
190 throw std::range_error(
"could not find valid method" ) ;
193 m->operator()(
XP(
object), args );
201 SEXP
invoke_void( SEXP method_xp, SEXP
object, SEXP *args,
int nargs ){
205 typename vec_signed_method::iterator it = mets->begin() ;
206 size_t n = mets->size() ;
209 for(
size_t i=0; i<n; i++, ++it ){
210 if( ( (*it)->valid )( args, nargs) ){
217 throw std::range_error(
"could not find valid method" ) ;
219 m->operator()(
XP(
object), args );
227 typename vec_signed_method::iterator it = mets->begin() ;
228 size_t n = mets->size() ;
231 for(
size_t i=0; i<n; i++, ++it ){
232 if( ( (*it)->valid )( args, nargs) ){
239 throw std::range_error(
"could not find valid method" ) ;
241 return m->operator()(
XP(
object), args ) ;
247 RCPP_DEBUG_MODULE_1(
"AddMethod( %s, method_class* m, ValidMethod valid = &yes, const char* docstring = 0", name_ )
249 typename map_vec_signed_method::iterator it = ptr->
vec_methods.find( name_ ) ;
254 if( *name_ ==
'[' ) ptr->
specials++ ;
263 template <
typename RESULT_TYPE,
typename... T>
264 self&
method(
const char* name_, RESULT_TYPE (Class::*fun)(T...),
265 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
266 AddMethod( name_,
new CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
269 template <
typename RESULT_TYPE,
typename... T>
270 self&
method(
const char* name_, RESULT_TYPE (Class::*fun)(T...)
const,
271 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
272 AddMethod( name_,
new const_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
275 template <
typename RESULT_TYPE,
typename... T>
277 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
278 AddMethod( name_,
new CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
281 template <
typename RESULT_TYPE,
typename... T>
283 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
284 AddMethod( name_,
new const_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
287 template <
typename RESULT_TYPE,
typename... T>
288 self&
method(
const char* name_, RESULT_TYPE (*fun)(Class*, T...),
289 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
290 AddMethod( name_,
new Pointer_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
293 template <
typename RESULT_TYPE,
typename... T>
295 const char* docstring = 0, ValidMethod valid = &yes_arity<
sizeof...(T)>) {
296 AddMethod( name_,
new Const_Pointer_CppMethodN<Class,RESULT_TYPE,T...>(fun), valid, docstring);
307 typename PROPERTY_MAP::iterator it =
properties.find( p ) ;
308 if( it ==
properties.end() )
throw std::range_error(
"no such property" ) ;
309 return it->second->is_readonly() ;
312 typename PROPERTY_MAP::iterator it =
properties.find( p ) ;
313 if( it ==
properties.end() )
throw std::range_error(
"no such property" ) ;
314 return it->second->get_class() ;
320 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
321 for(
size_t i=0; i<s; i++, ++it){
322 n += (it->second)->size() ;
327 for(
size_t i=0; i<s; i++, ++it){
328 n = (it->second)->size() ;
329 std::string name = it->first ;
330 for(
size_t j=0; j<n; j++, k++){
340 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
341 for(
size_t i=0; i<s; i++, ++it){
342 n += (it->second)->size() ;
348 for(
size_t i=0; i<s; i++, ++it){
349 n = (it->second)->size() ;
350 std::string name = it->first ;
351 typename vec_signed_method::iterator m_it = (it->second)->begin() ;
352 for(
size_t j=0; j<n; j++, k++, ++m_it){
354 res[k] = (*m_it)->nargs() ;
357 res.
names( ) = mnames ;
364 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
365 for(
size_t i=0; i<s; i++, ++it){
366 n += (it->second)->size() ;
372 for(
size_t i=0; i<s; i++, ++it){
373 n = (it->second)->size() ;
374 std::string name = it->first ;
375 typename vec_signed_method::iterator m_it = (it->second)->begin() ;
376 for(
size_t j=0; j<n; j++, k++, ++m_it){
378 res[k] = (*m_it)->is_void() ;
381 res.
names( ) = mnames ;
389 typename PROPERTY_MAP::iterator it =
properties.begin( ) ;
390 for(
size_t i=0; i<n; i++, ++it){
400 typename PROPERTY_MAP::iterator it =
properties.begin( ) ;
401 for(
size_t i=0; i<n; i++, ++it){
402 pnames[i] = it->first ;
403 out[i] = it->second->get_class() ;
405 out.
names() = pnames ;
413 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
418 if( buffer[0] ==
'[' ) continue ;
428 typename PROPERTY_MAP::iterator prop_it =
properties.begin();
429 for( ; i<ntotal; i++, ++prop_it){
430 out[i] = prop_it->first ;
438 return prop->get(
XP(
object) );
445 return prop->set(
XP(
object), value );
454 typename PROPERTY_MAP::iterator it =
properties.begin( ) ;
455 for(
size_t i=0; i<n; i++, ++it){
456 pnames[i] = it->first ;
457 out[i] = S4_field<Class>( it->second, class_xp ) ;
459 out.
names() = pnames ;
464 RCPP_DEBUG_MODULE(
"Rcpp::List getMethods( const XP_Class& class_xp, std::string& buffer" )
465 #if RCPP_DEBUG_LEVEL > 0
466 Rf_PrintValue( class_xp ) ;
471 typename map_vec_signed_method::iterator it =
vec_methods.begin( ) ;
473 for(
size_t i=0; i<n; i++, ++it){
474 mnames[i] = it->first ;
476 res[i] = S4_CppOverloadedMethods<Class>( v , class_xp, it->first.c_str(), buffer ) ;
478 res.
names() = mnames ;
485 typename vec_signed_constructor::iterator it =
constructors.begin( ) ;
486 for(
size_t i=0; i<n; i++, ++it){
487 out[i] = S4_CppConstructor<Class>( *it , class_xp, name, buffer ) ;
527 template <
typename PARENT>
530 typedef typename parent_class_::signed_method_class parent_signed_method_class ;
531 typedef typename parent_class_::method_class parent_method_class ;
534 parent_class_* parent_class_pointer =
reinterpret_cast< parent_class_*
> ( scope->get_class_pointer( parent ) );
537 typename parent_class_::map_vec_signed_method::iterator parent_vec_methods_iterator = parent_class_pointer->vec_methods.begin() ;
538 typename parent_class_::map_vec_signed_method::iterator parent_vec_methods_end = parent_class_pointer->vec_methods.end() ;
539 std::string method_name ;
540 for( ; parent_vec_methods_iterator != parent_vec_methods_end; parent_vec_methods_iterator++){
541 method_name = parent_vec_methods_iterator->first ;
543 typedef typename parent_class_::vec_signed_method parent_vec_signed_method ;
544 parent_vec_signed_method* p_methods = parent_vec_methods_iterator->second ;
545 typename parent_vec_signed_method::iterator methods_it = p_methods->begin() ;
546 typename parent_vec_signed_method::iterator methods_end = p_methods->end() ;
548 for( ; methods_it != methods_end; methods_it++){
549 parent_signed_method_class* signed_method = *methods_it ;
550 parent_method_class* parent_method = signed_method->method ;
552 CppMethod<Class>*
method =
new CppInheritedMethod<Class,PARENT>( parent_method ) ;
554 AddMethod( method_name.c_str(),
method, signed_method->valid , signed_method->docstring.c_str() ) ;
560 typedef typename parent_class_::PROPERTY_MAP parent_PROPERTY_MAP ;
561 typedef typename parent_PROPERTY_MAP::iterator parent_PROPERTY_MAP_iterator ;
563 parent_PROPERTY_MAP_iterator parent_property_it = parent_class_pointer->properties.begin() ;
564 parent_PROPERTY_MAP_iterator parent_property_end = parent_class_pointer->properties.end() ;
565 for( ; parent_property_it != parent_property_end; parent_property_it++){
567 parent_property_it->first.c_str(),
568 new CppInheritedProperty<Class,PARENT>( parent_property_it->second )
572 std::string buffer(
"Rcpp_" ) ; buffer += parent ;
CppProperty< Class > prop_class
void SetFinalizer(finalizer_class *f)
SignedMethod< Class > signed_method_class
std::map< std::string, prop_class * > PROPERTY_MAP
self & method(const char *name_, RESULT_TYPE(Class::*fun)(T...), const char *docstring=0, ValidMethod valid=&yes_arity< sizeof...(T)>)
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 & constructor(const char *docstring=0, ValidConstructor valid=&yes_arity< sizeof...(T)>)
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)
self & factory(Class *(*fun)(T...), const char *docstring=0, ValidConstructor valid=&yes_arity< sizeof...(T)>)
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)
self & method(const char *name_, RESULT_TYPE(*fun)(Class *, T...), const char *docstring=0, ValidMethod valid=&yes_arity< sizeof...(T)>)
self & nonconst_method(const char *name_, RESULT_TYPE(Class::*fun)(T...), const char *docstring=0, ValidMethod valid=&yes_arity< sizeof...(T)>)
self & method(const char *name_, RESULT_TYPE(Class::*fun)(T...) const, const char *docstring=0, ValidMethod valid=&yes_arity< sizeof...(T)>)
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
self & const_method(const char *name_, RESULT_TYPE(Class::*fun)(T...) const, const char *docstring=0, ValidMethod valid=&yes_arity< sizeof...(T)>)
Rcpp::IntegerVector methods_arity()
self & const_method(const char *name_, RESULT_TYPE(*fun)(const Class *, T...), const char *docstring=0, ValidMethod valid=&yes_arity< sizeof...(T)>)
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__)
Rcpp::XPtr< Rcpp::class_Base > XP_Class
Vector< STRSXP > CharacterVector
Vector< LGLSXP > LogicalVector
Vector< INTSXP > IntegerVector
attribute_hidden Rcpp::Module * getCurrentScope()