ExtensionModule.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef __CXX_ExtensionModule__h
00039 #define __CXX_ExtensionModule__h
00040
00041 namespace Py
00042 {
00043 class PYCXX_EXPORT ExtensionModuleBase
00044 {
00045 public:
00046 ExtensionModuleBase( const char *name );
00047 virtual ~ExtensionModuleBase();
00048
00049 Module module( void ) const;
00050 Dict moduleDictionary( void ) const;
00051
00052 virtual Object invoke_method_noargs( void *method_def ) = 0;
00053 virtual Object invoke_method_keyword( void *method_def, const Tuple &_args, const Dict &_keywords ) = 0;
00054 virtual Object invoke_method_varargs( void *method_def, const Tuple &_args ) = 0;
00055
00056 const std::string &name() const;
00057 const std::string &fullName() const;
00058
00059
00060 Object moduleObject( void ) const;
00061
00062 protected:
00063
00064 void initialize( const char *module_doc );
00065
00066 const std::string m_module_name;
00067 const std::string m_full_module_name;
00068 MethodTable m_method_table;
00069 #if PY3
00070 PyModuleDef m_module_def;
00071 #endif
00072 PyObject *m_module;
00073
00074 private:
00075
00076
00077
00078 ExtensionModuleBase( const ExtensionModuleBase & );
00079 void operator=( const ExtensionModuleBase & );
00080 };
00081
00082
00083 extern "C" PYCXX_EXPORT PyObject *method_noargs_call_handler( PyObject *_self_and_name_tuple, PyObject * );
00084 extern "C" PYCXX_EXPORT PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args );
00085 extern "C" PYCXX_EXPORT PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords );
00086
00087 extern "C" PYCXX_EXPORT void do_not_dealloc( void * );
00088
00089 template<TEMPLATE_TYPENAME T>
00090 class ExtensionModule : public ExtensionModuleBase
00091 {
00092 public:
00093 ExtensionModule( const char *name )
00094 : ExtensionModuleBase( name )
00095 {}
00096 virtual ~ExtensionModule()
00097 {}
00098
00099 protected:
00100 typedef Object (T::*method_noargs_function_t)();
00101 typedef Object (T::*method_varargs_function_t)( const Tuple &args );
00102 typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
00103 typedef std::map<std::string, MethodDefExt<T> *> method_map_t;
00104
00105 static void add_noargs_method( const char *name, method_noargs_function_t function, const char *doc="" )
00106 {
00107 method_map_t &mm = methods();
00108 mm[ std::string( name ) ] = new MethodDefExt<T>( name, function, method_noargs_call_handler, doc );
00109 }
00110
00111 static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
00112 {
00113 method_map_t &mm = methods();
00114 mm[ std::string( name ) ] = new MethodDefExt<T>( name, function, method_varargs_call_handler, doc );
00115 }
00116
00117 static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
00118 {
00119 method_map_t &mm = methods();
00120 mm[ std::string( name ) ] = new MethodDefExt<T>( name, function, method_keyword_call_handler, doc );
00121 }
00122
00123 void initialize( const char *module_doc="" )
00124 {
00125 ExtensionModuleBase::initialize( module_doc );
00126 Dict dict( moduleDictionary() );
00127
00128
00129
00130
00131
00132 method_map_t &mm = methods();
00133 EXPLICIT_TYPENAME method_map_t::const_iterator i = mm.begin();
00134 EXPLICIT_TYPENAME method_map_t::const_iterator i_end = mm.end();
00135 for ( ; i != i_end; ++i )
00136 {
00137 MethodDefExt<T> *method_def = (*i).second;
00138
00139 static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
00140
00141 Tuple args( 2 );
00142 args[0] = Object( self );
00143 args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) );
00144
00145 PyObject *func = PyCFunction_New
00146 (
00147 &method_def->ext_meth_def,
00148 new_reference_to( args )
00149 );
00150
00151 method_def->py_method = Object( func, true );
00152
00153 dict[ (*i).first ] = method_def->py_method;
00154 }
00155 }
00156
00157 protected:
00158 static method_map_t &methods( void )
00159 {
00160 static method_map_t *map_of_methods = NULL;
00161 if( map_of_methods == NULL )
00162 map_of_methods = new method_map_t;
00163
00164 return *map_of_methods;
00165 }
00166
00167
00168 virtual Object invoke_method_noargs( void *method_def )
00169 {
00170
00171 T *self = static_cast<T *>( this );
00172 MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>( method_def );
00173
00174 return (self->*meth_def->ext_noargs_function)();
00175 }
00176
00177
00178 virtual Object invoke_method_varargs( void *method_def, const Tuple &args )
00179 {
00180
00181 T *self = static_cast<T *>( this );
00182 MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>( method_def );
00183
00184 return (self->*meth_def->ext_varargs_function)( args );
00185 }
00186
00187
00188 virtual Object invoke_method_keyword( void *method_def, const Tuple &args, const Dict &keywords )
00189 {
00190
00191 T *self = static_cast<T *>( this );
00192 MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>( method_def );
00193
00194 return (self->*meth_def->ext_keyword_function)( args, keywords );
00195 }
00196
00197 private:
00198
00199
00200
00201 ExtensionModule( const ExtensionModule<T> & );
00202 void operator=( const ExtensionModule<T> & );
00203 };
00204 }
00205
00206
00207
00208 #endif