ExtensionOldType.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_ExtensionOldType__h
00039 #define __CXX_ExtensionOldType__h
00040
00041 namespace Py
00042 {
00043 template<TEMPLATE_TYPENAME T> class PythonExtension
00044 : public PythonExtensionBase
00045 {
00046 public:
00047 static PyTypeObject *type_object()
00048 {
00049 return behaviors().type_object();
00050 }
00051
00052 static bool check( PyObject *p )
00053 {
00054
00055 return p->ob_type == type_object();
00056 }
00057
00058 static bool check( const Object &ob )
00059 {
00060 return check( ob.ptr() );
00061 }
00062
00063
00064
00065
00066
00067 virtual Object getattr( const char *name )
00068 {
00069 return getattr_methods( name );
00070 }
00071
00072 PyObject *selfPtr()
00073 {
00074 return this;
00075 }
00076
00077 Object self()
00078 {
00079 return asObject( this );
00080 }
00081
00082 protected:
00083 explicit PythonExtension()
00084 : PythonExtensionBase()
00085 {
00086 PyObject_Init( this, type_object() );
00087
00088
00089 behaviors().supportGetattr();
00090 }
00091
00092 virtual ~PythonExtension()
00093 {}
00094
00095 static PythonType &behaviors()
00096 {
00097 static PythonType* p;
00098 if( p == NULL )
00099 {
00100 #if defined( _CPPRTTI ) || defined( __GNUG__ )
00101 const char *default_name =( typeid( T ) ).name();
00102 #else
00103 const char *default_name = "unknown";
00104 #endif
00105 p = new PythonType( sizeof( T ), 0, default_name );
00106 p->set_tp_dealloc( extension_object_deallocator );
00107 }
00108
00109 return *p;
00110 }
00111
00112 typedef Object (T::*method_noargs_function_t)();
00113 typedef Object (T::*method_varargs_function_t)( const Tuple &args );
00114 typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
00115 typedef std::map<std::string, MethodDefExt<T> *> method_map_t;
00116
00117
00118 virtual Object getattr_default( const char *_name )
00119 {
00120 std::string name( _name );
00121
00122 if( name == "__name__" && type_object()->tp_name != NULL )
00123 {
00124 return Py::String( type_object()->tp_name );
00125 }
00126
00127 if( name == "__doc__" && type_object()->tp_doc != NULL )
00128 {
00129 return Py::String( type_object()->tp_doc );
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 return getattr_methods( _name );
00147 }
00148
00149
00150 virtual Object getattr_methods( const char *_name )
00151 {
00152 std::string name( _name );
00153
00154 method_map_t &mm = methods();
00155
00156
00157 EXPLICIT_TYPENAME method_map_t::const_iterator i = mm.find( name );
00158 if( i == mm.end() )
00159 {
00160 if( name == "__methods__" )
00161 {
00162 List methods;
00163
00164 i = mm.begin();
00165 EXPLICIT_TYPENAME method_map_t::const_iterator i_end = mm.end();
00166
00167 for( ; i != i_end; ++i )
00168 methods.append( String( (*i).first ) );
00169
00170 return methods;
00171 }
00172
00173 throw AttributeError( name );
00174 }
00175
00176 MethodDefExt<T> *method_def = i->second;
00177
00178 Tuple self( 2 );
00179
00180 self[0] = Object( this );
00181 self[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) );
00182
00183 PyObject *func = PyCFunction_New( &method_def->ext_meth_def, self.ptr() );
00184
00185 return Object(func, true);
00186 }
00187
00188
00189 static void check_unique_method_name( const char *name )
00190 {
00191 method_map_t &mm = methods();
00192 EXPLICIT_TYPENAME method_map_t::const_iterator i;
00193 i = mm.find( name );
00194 if( i != mm.end() )
00195 throw AttributeError( name );
00196 }
00197
00198 static void add_noargs_method( const char *name, method_noargs_function_t function, const char *doc="" )
00199 {
00200 check_unique_method_name( name );
00201 method_map_t &mm = methods();
00202 mm[ std::string( name ) ] = new MethodDefExt<T>( name, function, method_noargs_call_handler, doc );
00203 }
00204
00205 static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
00206 {
00207 check_unique_method_name( name );
00208 method_map_t &mm = methods();
00209 mm[ std::string( name ) ] = new MethodDefExt<T>( name, function, method_varargs_call_handler, doc );
00210 }
00211
00212 static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
00213 {
00214 check_unique_method_name( name );
00215 method_map_t &mm = methods();
00216 mm[ std::string( name ) ] = new MethodDefExt<T>( name, function, method_keyword_call_handler, doc );
00217 }
00218
00219 private:
00220 static method_map_t &methods( void )
00221 {
00222 static method_map_t *map_of_methods = NULL;
00223 if( map_of_methods == NULL )
00224 map_of_methods = new method_map_t;
00225
00226 return *map_of_methods;
00227 }
00228
00229
00230 static PyObject *method_noargs_call_handler( PyObject *_self_and_name_tuple, PyObject * )
00231 {
00232 try
00233 {
00234 Tuple self_and_name_tuple( _self_and_name_tuple );
00235
00236 PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
00237 T *self = static_cast<T *>( self_in_cobject );
00238 MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>(
00239 PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) );
00240 Object result;
00241
00242
00243 #ifdef _STLP_DEBUG
00244 try
00245 {
00246 result = (self->*meth_def->ext_noargs_function)();
00247 }
00248 catch( std::__stl_debug_exception )
00249 {
00250
00251 throw RuntimeError( "Error message not set yet." );
00252 }
00253 #else
00254 result = (self->*meth_def->ext_noargs_function)();
00255 #endif // _STLP_DEBUG
00256
00257 return new_reference_to( result.ptr() );
00258 }
00259 catch( Exception & )
00260 {
00261 return 0;
00262 }
00263 }
00264
00265 static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
00266 {
00267 try
00268 {
00269 Tuple self_and_name_tuple( _self_and_name_tuple );
00270
00271 PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
00272 T *self = static_cast<T *>( self_in_cobject );
00273
00274 MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>(
00275 PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) );
00276 Tuple args( _args );
00277
00278 Object result;
00279
00280
00281 #ifdef _STLP_DEBUG
00282 try
00283 {
00284 result = (self->*meth_def->ext_varargs_function)( args );
00285 }
00286 catch( std::__stl_debug_exception )
00287 {
00288 throw RuntimeError( "Error message not set yet." );
00289 }
00290 #else
00291 result = (self->*meth_def->ext_varargs_function)( args );
00292 #endif // _STLP_DEBUG
00293
00294 return new_reference_to( result.ptr() );
00295 }
00296 catch( Exception & )
00297 {
00298 return 0;
00299 }
00300 }
00301
00302 static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
00303 {
00304 try
00305 {
00306 Tuple self_and_name_tuple( _self_and_name_tuple );
00307
00308 PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
00309 T *self = static_cast<T *>( self_in_cobject );
00310
00311 MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>(
00312 PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) );
00313
00314 Tuple args( _args );
00315
00316
00317 Dict keywords;
00318 if( _keywords != NULL )
00319 keywords = Dict( _keywords );
00320
00321 Object result( ( self->*meth_def->ext_keyword_function )( args, keywords ) );
00322
00323 return new_reference_to( result.ptr() );
00324 }
00325 catch( Exception & )
00326 {
00327 return 0;
00328 }
00329 }
00330
00331 static void extension_object_deallocator( PyObject* t )
00332 {
00333 delete (T *)( t );
00334 }
00335
00336
00337
00338
00339 explicit PythonExtension( const PythonExtension<T> &other );
00340 void operator=( const PythonExtension<T> &rhs );
00341 };
00342
00343
00344
00345
00346 template<TEMPLATE_TYPENAME T>
00347 class ExtensionObject: public Object
00348 {
00349 public:
00350
00351 explicit ExtensionObject( PyObject *pyob )
00352 : Object( pyob )
00353 {
00354 validate();
00355 }
00356
00357 ExtensionObject( const ExtensionObject<T> &other )
00358 : Object( *other )
00359 {
00360 validate();
00361 }
00362
00363 ExtensionObject( const Object &other )
00364 : Object( *other )
00365 {
00366 validate();
00367 }
00368
00369 ExtensionObject &operator=( const Object &rhs )
00370 {
00371 return( *this = *rhs );
00372 }
00373
00374 ExtensionObject &operator=( PyObject *rhsp )
00375 {
00376 if( ptr() != rhsp )
00377 set( rhsp );
00378 return *this;
00379 }
00380
00381 virtual bool accepts( PyObject *pyob ) const
00382 {
00383 return( pyob && T::check( pyob ) );
00384 }
00385
00386
00387
00388
00389 T *extensionObject( void )
00390 {
00391 return static_cast<T *>( ptr() );
00392 }
00393 };
00394 }
00395
00396
00397 #endif