1
//----------------------------------*-C++-*----------------------------------//
2
// Copyright 1998 The Regents of the University of California.
3
// All rights reserved. See LEGAL.LLNL for full text and disclaimer.
4
//---------------------------------------------------------------------------//
6
#ifndef __CXX_Extensions__h
7
#define __CXX_Extensions__h
11
// disable warning C4786: symbol greater than 255 character,
13
#pragma warning(disable: 4786)
17
#include "CXX/Version.hxx"
18
#include "CXX/Config.hxx"
19
#include "CXX/Objects.hxx"
23
extern PyObject py_object_initializer;
31
class ExtensionModuleBase;
33
// Make an Exception Type for use in raising custom exceptions
34
class ExtensionExceptionType : public Object
37
ExtensionExceptionType();
38
virtual ~ExtensionExceptionType();
40
// call init to create the type
41
void init( ExtensionModuleBase &module, const std::string& name, ExtensionExceptionType &parent );
42
void init( ExtensionModuleBase &module, const std::string& name );
50
virtual ~MethodTable();
52
void add(const char* method_name, PyCFunction f, const char* doc="", int flag=1);
56
std::vector<PyMethodDef> t; // accumulator of PyMethodDef's
57
PyMethodDef *mt; // Actual method table produced when full
59
static PyMethodDef method (const char* method_name, PyCFunction f, int flags = 1, const char* doc="");
63
// prevent the compiler generating these unwanted functions
65
MethodTable(const MethodTable& m); //unimplemented
66
void operator=(const MethodTable& m); //unimplemented
68
}; // end class MethodTable
72
typedef PyObject *(*method_varargs_call_handler_t)( PyObject *_self, PyObject *_args );
73
typedef PyObject *(*method_keyword_call_handler_t)( PyObject *_self, PyObject *_args, PyObject *_dict );
77
class MethodDefExt : public PyMethodDef
80
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
81
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
86
method_varargs_function_t _function,
87
method_varargs_call_handler_t _handler,
91
ext_meth_def.ml_name = const_cast<char *>(_name);
92
ext_meth_def.ml_meth = _handler;
93
ext_meth_def.ml_flags = METH_VARARGS;
94
ext_meth_def.ml_doc = const_cast<char *>(_doc);
96
ext_varargs_function = _function;
97
ext_keyword_function = NULL;
103
method_keyword_function_t _function,
104
method_keyword_call_handler_t _handler,
108
ext_meth_def.ml_name = const_cast<char *>(_name);
109
ext_meth_def.ml_meth = method_varargs_call_handler_t( _handler );
110
ext_meth_def.ml_flags = METH_VARARGS|METH_KEYWORDS;
111
ext_meth_def.ml_doc = const_cast<char *>(_doc);
113
ext_varargs_function = NULL;
114
ext_keyword_function = _function;
120
PyMethodDef ext_meth_def;
121
method_varargs_function_t ext_varargs_function;
122
method_keyword_function_t ext_keyword_function;
125
class ExtensionModuleBase
128
ExtensionModuleBase( const char *name );
129
virtual ~ExtensionModuleBase();
131
Module module(void) const; // only valid after initialize() has been called
132
Dict moduleDictionary(void) const; // only valid after initialize() has been called
134
virtual Object invoke_method_keyword( const std::string &_name, const Tuple &_args, const Dict &_keywords ) = 0;
135
virtual Object invoke_method_varargs( const std::string &_name, const Tuple &_args ) = 0;
137
const std::string &name() const;
138
const std::string &fullName() const;
141
// Initialize the module
142
void initialize( const char *module_doc );
144
const std::string module_name;
145
const std::string full_module_name;
146
MethodTable method_table;
151
// prevent the compiler generating these unwanted functions
153
ExtensionModuleBase( const ExtensionModuleBase & ); //unimplemented
154
void operator=( const ExtensionModuleBase & ); //unimplemented
158
extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords );
159
extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args );
160
extern "C" void do_not_dealloc( void * );
163
template<TEMPLATE_TYPENAME T>
164
class ExtensionModule : public ExtensionModuleBase
167
ExtensionModule( const char *name )
168
: ExtensionModuleBase( name )
170
virtual ~ExtensionModule()
174
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
175
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
176
typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
178
static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
180
method_map_t &mm = methods();
182
MethodDefExt<T> *method_definition = new MethodDefExt<T>
186
method_varargs_call_handler,
190
mm[std::string( name )] = method_definition;
193
static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
195
method_map_t &mm = methods();
197
MethodDefExt<T> *method_definition = new MethodDefExt<T>
201
method_keyword_call_handler,
205
mm[std::string( name )] = method_definition;
208
void initialize( const char *module_doc="" )
210
ExtensionModuleBase::initialize( module_doc );
211
Dict dict( moduleDictionary() );
214
// put each of the methods into the modules dictionary
215
// so that we get called back at the function in T.
217
method_map_t &mm = methods();
218
EXPLICIT_TYPENAME method_map_t::iterator i;
220
for( i=mm.begin(); i != mm.end(); ++i )
222
MethodDefExt<T> *method_definition = (*i).second;
224
static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
227
args[0] = Object( self );
228
args[1] = String( (*i).first );
230
PyObject *func = PyCFunction_New
232
&method_definition->ext_meth_def,
233
new_reference_to( args )
236
dict[ (*i).first ] = Object( func );
240
protected: // Tom Malcolmson reports that derived classes need access to these
242
static method_map_t &methods(void)
244
static method_map_t *map_of_methods = NULL;
245
if( map_of_methods == NULL )
246
map_of_methods = new method_map_t;
248
return *map_of_methods;
252
// this invoke function must be called from within a try catch block
253
virtual Object invoke_method_keyword( const std::string &name, const Tuple &args, const Dict &keywords )
255
method_map_t &mm = methods();
256
MethodDefExt<T> *meth_def = mm[ name ];
257
if( meth_def == NULL )
259
std::string error_msg( "CXX - cannot invoke keyword method named " );
261
throw RuntimeError( error_msg );
264
// cast up to the derived class
265
T *self = static_cast<T *>(this);
267
return (self->*meth_def->ext_keyword_function)( args, keywords );
270
// this invoke function must be called from within a try catch block
271
virtual Object invoke_method_varargs( const std::string &name, const Tuple &args )
273
method_map_t &mm = methods();
274
MethodDefExt<T> *meth_def = mm[ name ];
275
if( meth_def == NULL )
277
std::string error_msg( "CXX - cannot invoke varargs method named " );
279
throw RuntimeError( error_msg );
282
// cast up to the derived class
283
T *self = static_cast<T *>(this);
285
return (self->*meth_def->ext_varargs_function)( args );
290
// prevent the compiler generating these unwanted functions
292
ExtensionModule( const ExtensionModule<T> & ); //unimplemented
293
void operator=( const ExtensionModule<T> & ); //unimplemented
300
// if you define one sequence method you must define
301
// all of them except the assigns
303
PythonType (size_t base_size, int itemsize, const char *default_name );
304
virtual ~PythonType ();
306
const char *getName () const;
307
const char *getDoc () const;
309
PyTypeObject* type_object () const;
310
void name (const char* nam);
311
void doc (const char* d);
312
void dealloc(void (*f)(PyObject*));
314
void supportPrint(void);
315
void supportGetattr(void);
316
void supportSetattr(void);
317
void supportGetattro(void);
318
void supportSetattro(void);
319
void supportCompare(void);
320
void supportRepr(void);
321
void supportStr(void);
322
void supportHash(void);
323
void supportCall(void);
324
void supportIter(void);
326
void supportSequenceType(void);
327
void supportMappingType(void);
328
void supportNumberType(void);
329
void supportBufferType(void);
333
PySequenceMethods *sequence_table;
334
PyMappingMethods *mapping_table;
335
PyNumberMethods *number_table;
336
PyBufferProcs *buffer_table;
338
void init_sequence();
345
// prevent the compiler generating these unwanted functions
347
PythonType (const PythonType& tb); // unimplemented
348
void operator=(const PythonType& t); // unimplemented
350
}; // end of PythonType
354
// Class PythonExtension is what you inherit from to create
355
// a new Python extension type. You give your class itself
356
// as the template paramter.
358
// There are two ways that extension objects can get destroyed.
359
// 1. Their reference count goes to zero
360
// 2. Someone does an explicit delete on a pointer.
361
// In (1) the problem is to get the destructor called
362
// We register a special deallocator in the Python type object
363
// (see behaviors()) to do this.
364
// In (2) there is no problem, the dtor gets called.
366
// PythonExtension does not use the usual Python heap allocator,
367
// instead using new/delete. We do the setting of the type object
368
// and reference count, usually done by PyObject_New, in the
371
// This special deallocator does a delete on the pointer.
374
class PythonExtensionBase : public PyObject
377
PythonExtensionBase();
378
virtual ~PythonExtensionBase();
381
virtual int print( FILE *, int );
382
virtual Object getattr( const char * ) = 0;
383
virtual int setattr( const char *, const Object & );
384
virtual Object getattro( const Object & );
385
virtual int setattro( const Object &, const Object & );
386
virtual int compare( const Object & );
387
virtual Object repr();
388
virtual Object str();
390
virtual Object call( const Object &, const Object & );
391
virtual Object iter();
392
virtual PyObject* iternext();
395
virtual int sequence_length();
396
virtual Object sequence_concat( const Object & );
397
virtual Object sequence_repeat( int );
398
virtual Object sequence_item( int );
399
virtual Object sequence_slice( int, int );
400
virtual int sequence_ass_item( int, const Object & );
401
virtual int sequence_ass_slice( int, int, const Object & );
404
virtual int mapping_length();
405
virtual Object mapping_subscript( const Object & );
406
virtual int mapping_ass_subscript( const Object &, const Object & );
409
virtual int number_nonzero();
410
virtual Object number_negative();
411
virtual Object number_positive();
412
virtual Object number_absolute();
413
virtual Object number_invert();
414
virtual Object number_int();
415
virtual Object number_float();
416
virtual Object number_long();
417
virtual Object number_oct();
418
virtual Object number_hex();
419
virtual Object number_add( const Object & );
420
virtual Object number_subtract( const Object & );
421
virtual Object number_multiply( const Object & );
422
virtual Object number_divide( const Object & );
423
virtual Object number_remainder( const Object & );
424
virtual Object number_divmod( const Object & );
425
virtual Object number_lshift( const Object & );
426
virtual Object number_rshift( const Object & );
427
virtual Object number_and( const Object & );
428
virtual Object number_xor( const Object & );
429
virtual Object number_or( const Object & );
430
virtual Object number_power( const Object &, const Object & );
433
virtual int buffer_getreadbuffer( int, void** );
434
virtual int buffer_getwritebuffer( int, void** );
435
virtual int buffer_getsegcount( int* );
438
void missing_method( void );
439
static PyObject *method_call_handler( PyObject *self, PyObject *args );
442
template<TEMPLATE_TYPENAME T>
443
class PythonExtension: public PythonExtensionBase
446
static PyTypeObject* type_object()
448
return behaviors().type_object();
451
static int check( PyObject *p )
454
return p->ob_type == type_object();
457
static int check( const Object& ob )
459
return check( ob.ptr());
464
// every object needs getattr implemented
465
// to support methods
467
virtual Object getattr( const char *name )
469
return getattr_methods( name );
473
explicit PythonExtension()
474
: PythonExtensionBase()
477
PyObject_INIT( this, type_object() );
480
ob_type = type_object();
483
// every object must support getattr
484
behaviors().supportGetattr();
487
virtual ~PythonExtension()
490
static PythonType &behaviors()
492
static PythonType* p;
495
#if defined( _CPPRTTI ) || defined(__GNUG__)
496
const char *default_name = (typeid ( T )).name();
498
const char *default_name = "unknown";
500
p = new PythonType( sizeof( T ), 0, default_name );
501
p->dealloc( extension_object_deallocator );
508
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
509
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
510
typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
512
// support the default attributes, __name__, __doc__ and methods
513
virtual Object getattr_default( const char *_name )
515
std::string name( _name );
517
if( name == "__name__" && type_object()->tp_name != NULL )
519
return Py::String( type_object()->tp_name );
521
else if( name == "__doc__" && type_object()->tp_doc != NULL )
523
return Py::String( type_object()->tp_doc );
526
// trying to fake out being a class for help()
527
// else if( name == "__bases__" )
529
// return Py::Tuple(0);
531
// else if( name == "__module__" )
533
// return Py::Nothing();
535
// else if( name == "__dict__" )
537
// return Py::Dict();
541
return getattr_methods( _name );
545
// turn a name into function object
546
virtual Object getattr_methods( const char *_name )
548
std::string name( _name );
550
method_map_t &mm = methods();
552
if( name == "__methods__" )
556
for( EXPLICIT_TYPENAME method_map_t::iterator i = mm.begin(); i != mm.end(); ++i )
557
methods.append( String( (*i).first ) );
562
// see if name exists
563
if( mm.find( name ) == mm.end() )
564
throw AttributeError( name );
568
self[0] = Object( this );
569
self[1] = String( name );
571
MethodDefExt<T> *method_definition = mm[ name ];
573
PyObject *func = PyCFunction_New( &method_definition->ext_meth_def, self.ptr() );
575
return Object(func, true);
578
static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
580
method_map_t &mm = methods();
582
MethodDefExt<T> *method_definition = new MethodDefExt<T>
586
method_varargs_call_handler,
590
mm[std::string( name )] = method_definition;
593
static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
595
method_map_t &mm = methods();
597
MethodDefExt<T> *method_definition = new MethodDefExt<T>
601
method_keyword_call_handler,
605
mm[std::string( name )] = method_definition;
609
static method_map_t &methods(void)
611
static method_map_t *map_of_methods = NULL;
612
if( map_of_methods == NULL )
613
map_of_methods = new method_map_t;
615
return *map_of_methods;
618
static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
622
Tuple self_and_name_tuple( _self_and_name_tuple );
624
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
625
T *self = static_cast<T *>( self_in_cobject );
627
String name( self_and_name_tuple[1] );
629
method_map_t &mm = methods();
630
MethodDefExt<T> *meth_def = mm[ name ];
631
if( meth_def == NULL )
636
// _keywords may be NULL so be careful about the way the dict is created
638
if( _keywords != NULL )
639
keywords = Dict( _keywords );
641
Object result( (self->*meth_def->ext_keyword_function)( args, keywords ) );
643
return new_reference_to( result.ptr() );
651
static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
655
Tuple self_and_name_tuple( _self_and_name_tuple );
657
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
658
T *self = static_cast<T *>( self_in_cobject );
660
String name( self_and_name_tuple[1] );
662
method_map_t &mm = methods();
663
MethodDefExt<T> *meth_def = mm[ name ];
664
if( meth_def == NULL )
671
// TMM: 7Jun'01 - Adding try & catch in case of STL debug-mode exceptions.
675
result = (self->*meth_def->ext_varargs_function)( args );
677
catch (std::__stl_debug_exception)
679
// throw cxx::RuntimeError( sErrMsg );
680
throw cxx::RuntimeError( "Error message not set yet." );
683
result = (self->*meth_def->ext_varargs_function)( args );
684
#endif // _STLP_DEBUG
686
return new_reference_to( result.ptr() );
694
static void extension_object_deallocator ( PyObject* t )
700
// prevent the compiler generating these unwanted functions
702
explicit PythonExtension( const PythonExtension<T>& other );
703
void operator=( const PythonExtension<T>& rhs );
707
// ExtensionObject<T> is an Object that will accept only T's.
709
template<TEMPLATE_TYPENAME T>
710
class ExtensionObject: public Object
714
explicit ExtensionObject ( PyObject *pyob )
720
ExtensionObject( const ExtensionObject<T>& other )
726
ExtensionObject( const Object& other )
732
ExtensionObject& operator= ( const Object& rhs )
734
return (*this = *rhs );
737
ExtensionObject& operator= ( PyObject* rhsp )
745
virtual bool accepts ( PyObject *pyob ) const
747
return ( pyob && T::check( pyob ));
751
// Obtain a pointer to the PythonExtension object
753
T *extensionObject(void)
755
return static_cast<T *>( ptr() );
760
// End of CXX_Extensions.h