~ubuntu-branches/ubuntu/breezy/pysvn/breezy

« back to all changes in this revision

Viewing changes to Import/pycxx_5_3_4/CXX/Extensions.hxx

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2005-09-08 05:13:33 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050908051333-qgsa2rksrb4az1h4
Tags: 1.3.0-1
Package from release tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
//---------------------------------------------------------------------------//
 
5
 
 
6
#ifndef __CXX_Extensions__h
 
7
#define __CXX_Extensions__h
 
8
 
 
9
 
 
10
#ifdef _MSC_VER
 
11
// disable warning C4786: symbol greater than 255 character,
 
12
// okay to ignore
 
13
#pragma warning(disable: 4786)
 
14
#endif
 
15
 
 
16
 
 
17
#include "CXX/Version.hxx"
 
18
#include "CXX/Config.hxx"
 
19
#include "CXX/Objects.hxx"
 
20
 
 
21
extern "C"
 
22
        {
 
23
        extern PyObject py_object_initializer;
 
24
        }
 
25
 
 
26
#include <vector>
 
27
#include <map>
 
28
 
 
29
namespace Py
 
30
        {
 
31
        class ExtensionModuleBase;
 
32
        
 
33
        // Make an Exception Type for use in raising custom exceptions
 
34
        class ExtensionExceptionType : public Object
 
35
                {
 
36
        public:
 
37
                ExtensionExceptionType();
 
38
                virtual ~ExtensionExceptionType();
 
39
 
 
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 );
 
43
                };
 
44
 
 
45
        
 
46
        class MethodTable 
 
47
                {
 
48
        public:
 
49
                MethodTable();
 
50
                virtual ~MethodTable();
 
51
                
 
52
                void add(const char* method_name, PyCFunction f, const char* doc="", int flag=1);
 
53
                PyMethodDef* table();
 
54
                
 
55
        protected:
 
56
                std::vector<PyMethodDef> t;     // accumulator of PyMethodDef's
 
57
                PyMethodDef *mt;                // Actual method table produced when full
 
58
                
 
59
                static PyMethodDef method (const char* method_name, PyCFunction f, int flags = 1, const char* doc="");
 
60
                
 
61
        private:
 
62
                //
 
63
                // prevent the compiler generating these unwanted functions
 
64
                //
 
65
                MethodTable(const MethodTable& m);      //unimplemented
 
66
                void operator=(const MethodTable& m);   //unimplemented
 
67
                
 
68
                }; // end class MethodTable
 
69
        
 
70
        extern "C"
 
71
                {
 
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 );
 
74
                };
 
75
        
 
76
        template<class T>
 
77
        class MethodDefExt : public PyMethodDef
 
78
                {
 
79
        public:
 
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 );
 
82
                
 
83
                MethodDefExt
 
84
                (
 
85
                const char *_name,
 
86
                method_varargs_function_t _function,
 
87
                method_varargs_call_handler_t _handler,
 
88
                const char *_doc
 
89
                )
 
90
                        {
 
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);
 
95
                        
 
96
                        ext_varargs_function = _function;
 
97
                        ext_keyword_function = NULL;
 
98
                        }
 
99
                
 
100
                MethodDefExt
 
101
                (
 
102
                const char *_name,
 
103
                method_keyword_function_t _function,
 
104
                method_keyword_call_handler_t _handler,
 
105
                const char *_doc
 
106
                )
 
107
                        {
 
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);
 
112
                        
 
113
                        ext_varargs_function = NULL;
 
114
                        ext_keyword_function = _function;
 
115
                        }
 
116
                
 
117
                ~MethodDefExt()
 
118
                        {}
 
119
                
 
120
                PyMethodDef ext_meth_def;
 
121
                method_varargs_function_t ext_varargs_function; 
 
122
                method_keyword_function_t ext_keyword_function; 
 
123
                };
 
124
        
 
125
        class ExtensionModuleBase
 
126
                {
 
127
        public:
 
128
                ExtensionModuleBase( const char *name );
 
129
                virtual ~ExtensionModuleBase();
 
130
                
 
131
                Module module(void) const;              // only valid after initialize() has been called
 
132
                Dict moduleDictionary(void) const;      // only valid after initialize() has been called
 
133
                
 
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;
 
136
                
 
137
                const std::string &name() const;
 
138
                const std::string &fullName() const;
 
139
        
 
140
        protected:
 
141
                // Initialize the module
 
142
                void initialize( const char *module_doc );
 
143
                
 
144
                const std::string module_name;
 
145
                const std::string full_module_name;
 
146
                MethodTable method_table;
 
147
                
 
148
        private:
 
149
                
 
150
                //
 
151
                // prevent the compiler generating these unwanted functions
 
152
                //
 
153
                ExtensionModuleBase( const ExtensionModuleBase & );     //unimplemented
 
154
                void operator=( const ExtensionModuleBase & );          //unimplemented
 
155
                
 
156
                };
 
157
        
 
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 * );
 
161
        
 
162
        
 
163
        template<TEMPLATE_TYPENAME T>
 
164
        class ExtensionModule : public ExtensionModuleBase
 
165
                {
 
166
        public:
 
167
                ExtensionModule( const char *name )
 
168
                        : ExtensionModuleBase( name )
 
169
                        {}
 
170
                virtual ~ExtensionModule()
 
171
                        {}
 
172
                
 
173
        protected:
 
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;
 
177
                
 
178
                static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
 
179
                        {
 
180
                        method_map_t &mm = methods();
 
181
                        
 
182
                        MethodDefExt<T> *method_definition = new MethodDefExt<T>
 
183
                        (
 
184
                        name,
 
185
                        function,
 
186
                        method_varargs_call_handler,
 
187
                        doc
 
188
                        );
 
189
                        
 
190
                        mm[std::string( name )] = method_definition;
 
191
                        }
 
192
                
 
193
                static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
 
194
                        {
 
195
                        method_map_t &mm = methods();
 
196
                        
 
197
                        MethodDefExt<T> *method_definition = new MethodDefExt<T>
 
198
                        (
 
199
                        name,
 
200
                        function,
 
201
                        method_keyword_call_handler,
 
202
                        doc
 
203
                        );
 
204
                        
 
205
                        mm[std::string( name )] = method_definition;
 
206
                        }
 
207
 
 
208
                void initialize( const char *module_doc="" )
 
209
                        {
 
210
                        ExtensionModuleBase::initialize( module_doc );
 
211
                        Dict dict( moduleDictionary() );
 
212
                        
 
213
                        //
 
214
                        // put each of the methods into the modules dictionary
 
215
                        // so that we get called back at the function in T.
 
216
                        //
 
217
                        method_map_t &mm = methods();
 
218
                        EXPLICIT_TYPENAME method_map_t::iterator i;
 
219
                        
 
220
                        for( i=mm.begin(); i != mm.end(); ++i )
 
221
                                {
 
222
                                MethodDefExt<T> *method_definition = (*i).second;
 
223
                                
 
224
                                static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
 
225
                                
 
226
                                Tuple args( 2 );
 
227
                                args[0] = Object( self );
 
228
                                args[1] = String( (*i).first );
 
229
                                
 
230
                                PyObject *func = PyCFunction_New
 
231
                                (
 
232
                                &method_definition->ext_meth_def,
 
233
                                new_reference_to( args )
 
234
                                );
 
235
                                
 
236
                                dict[ (*i).first ] = Object( func );
 
237
                                }
 
238
                        }
 
239
                
 
240
        protected:      // Tom Malcolmson reports that derived classes need access to these
 
241
                
 
242
                static method_map_t &methods(void)
 
243
                        {
 
244
                        static method_map_t *map_of_methods = NULL;
 
245
                        if( map_of_methods == NULL )
 
246
                        map_of_methods = new method_map_t;
 
247
                        
 
248
                        return *map_of_methods;
 
249
                        }
 
250
                
 
251
                
 
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 )
 
254
                        {
 
255
                        method_map_t &mm = methods();
 
256
                        MethodDefExt<T> *meth_def = mm[ name ];
 
257
                        if( meth_def == NULL )
 
258
                                {
 
259
                                std::string error_msg( "CXX - cannot invoke keyword method named " );
 
260
                                error_msg += name;
 
261
                                throw RuntimeError( error_msg );
 
262
                                }
 
263
                        
 
264
                        // cast up to the derived class
 
265
                        T *self = static_cast<T *>(this);
 
266
                        
 
267
                        return (self->*meth_def->ext_keyword_function)( args, keywords );
 
268
                        }
 
269
                
 
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 )
 
272
                        {
 
273
                        method_map_t &mm = methods();
 
274
                        MethodDefExt<T> *meth_def = mm[ name ];
 
275
                        if( meth_def == NULL )
 
276
                                {
 
277
                                std::string error_msg( "CXX - cannot invoke varargs method named " );
 
278
                                error_msg += name;
 
279
                                throw RuntimeError( error_msg );
 
280
                                }
 
281
                        
 
282
                        // cast up to the derived class
 
283
                        T *self = static_cast<T *>(this);
 
284
                        
 
285
                        return (self->*meth_def->ext_varargs_function)( args );
 
286
                        }
 
287
                
 
288
        private:
 
289
                //
 
290
                // prevent the compiler generating these unwanted functions
 
291
                //
 
292
                ExtensionModule( const ExtensionModule<T> & );  //unimplemented
 
293
                void operator=( const ExtensionModule<T> & );   //unimplemented
 
294
                };
 
295
        
 
296
        
 
297
        class PythonType
 
298
                {
 
299
        public:
 
300
                // if you define one sequence method you must define 
 
301
                // all of them except the assigns
 
302
                
 
303
                PythonType (size_t base_size, int itemsize, const char *default_name );
 
304
                virtual ~PythonType ();
 
305
                
 
306
                const char *getName () const;
 
307
                const char *getDoc () const;
 
308
 
 
309
                PyTypeObject* type_object () const;
 
310
                void name (const char* nam);
 
311
                void doc (const char* d);
 
312
                void dealloc(void (*f)(PyObject*));
 
313
                
 
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);
 
325
                
 
326
                void supportSequenceType(void);
 
327
                void supportMappingType(void);
 
328
                void supportNumberType(void);
 
329
                void supportBufferType(void);
 
330
                
 
331
        protected:
 
332
                PyTypeObject            *table;
 
333
                PySequenceMethods       *sequence_table;
 
334
                PyMappingMethods        *mapping_table;
 
335
                PyNumberMethods         *number_table;
 
336
                PyBufferProcs           *buffer_table;
 
337
                
 
338
                void init_sequence();
 
339
                void init_mapping();
 
340
                void init_number();
 
341
                void init_buffer();
 
342
                
 
343
        private:
 
344
                //
 
345
                // prevent the compiler generating these unwanted functions
 
346
                //
 
347
                PythonType (const PythonType& tb);      // unimplemented
 
348
                void operator=(const PythonType& t);    // unimplemented
 
349
                
 
350
                }; // end of PythonType
 
351
        
 
352
        
 
353
        
 
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.
 
357
        
 
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.
 
365
        
 
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 
 
369
        // base class ctor.
 
370
        
 
371
        // This special deallocator does a delete on the pointer.
 
372
        
 
373
        
 
374
        class PythonExtensionBase : public PyObject
 
375
                {
 
376
        public:
 
377
                PythonExtensionBase();
 
378
                virtual ~PythonExtensionBase();
 
379
                
 
380
        public:
 
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();
 
389
                virtual long hash();
 
390
                virtual Object call( const Object &, const Object & );
 
391
                virtual Object iter();
 
392
                virtual PyObject* iternext();
 
393
                
 
394
                // Sequence methods
 
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 & );
 
402
                
 
403
                // Mapping
 
404
                virtual int mapping_length();
 
405
                virtual Object mapping_subscript( const Object & );
 
406
                virtual int mapping_ass_subscript( const Object &, const Object & );
 
407
                
 
408
                // Number
 
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 & );
 
431
                
 
432
                // Buffer
 
433
                virtual int buffer_getreadbuffer( int, void** );
 
434
                virtual int buffer_getwritebuffer( int, void** );
 
435
                virtual int buffer_getsegcount( int* );
 
436
                
 
437
        private:
 
438
                void missing_method( void );
 
439
                static PyObject *method_call_handler( PyObject *self, PyObject *args );
 
440
                };
 
441
        
 
442
        template<TEMPLATE_TYPENAME T>
 
443
        class PythonExtension: public PythonExtensionBase 
 
444
                {
 
445
        public:
 
446
                static PyTypeObject* type_object() 
 
447
                        {
 
448
                        return behaviors().type_object();
 
449
                        }
 
450
                
 
451
                static int check( PyObject *p )
 
452
                        {
 
453
                        // is p like me?
 
454
                        return p->ob_type == type_object();
 
455
                        }
 
456
                
 
457
                static int check( const Object& ob )
 
458
                        {
 
459
                        return check( ob.ptr());
 
460
                        }
 
461
                
 
462
                
 
463
                //
 
464
                // every object needs getattr implemented
 
465
                // to support methods
 
466
                //
 
467
                virtual Object getattr( const char *name )
 
468
                        {
 
469
                        return getattr_methods( name );
 
470
                        }
 
471
                
 
472
        protected:
 
473
                explicit PythonExtension()
 
474
                        : PythonExtensionBase()
 
475
                        {
 
476
                        #ifdef PyObject_INIT
 
477
                        PyObject_INIT( this, type_object() );
 
478
                        #else
 
479
                        ob_refcnt = 1;
 
480
                        ob_type = type_object();
 
481
                        #endif
 
482
                        
 
483
                        // every object must support getattr
 
484
                        behaviors().supportGetattr();
 
485
                        }
 
486
                
 
487
                virtual ~PythonExtension()
 
488
                        {} 
 
489
                
 
490
                static PythonType &behaviors()
 
491
                        {
 
492
                        static PythonType* p;
 
493
                        if( p == NULL ) 
 
494
                                {
 
495
#if defined( _CPPRTTI ) || defined(__GNUG__)
 
496
                                const char *default_name = (typeid ( T )).name();
 
497
#else
 
498
                                const char *default_name = "unknown";
 
499
#endif
 
500
                                p = new PythonType( sizeof( T ), 0, default_name );
 
501
                                p->dealloc( extension_object_deallocator );
 
502
                                }
 
503
                        
 
504
                        return *p;
 
505
                        }
 
506
                
 
507
                
 
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;
 
511
                
 
512
                // support the default attributes, __name__, __doc__ and methods
 
513
                virtual Object getattr_default( const char *_name )
 
514
                        {
 
515
                        std::string name( _name );
 
516
 
 
517
                        if( name == "__name__" && type_object()->tp_name != NULL )
 
518
                                {
 
519
                                return Py::String( type_object()->tp_name );
 
520
                                }
 
521
                        else if( name == "__doc__" && type_object()->tp_doc != NULL )
 
522
                                {
 
523
                                return Py::String( type_object()->tp_doc );
 
524
                                }
 
525
 
 
526
// trying to fake out being a class for help()
 
527
//                      else if( name == "__bases__"  )
 
528
//                              {
 
529
//                              return Py::Tuple(0);
 
530
//                              }
 
531
//                      else if( name == "__module__"  )
 
532
//                              {
 
533
//                              return Py::Nothing();
 
534
//                              }
 
535
//                      else if( name == "__dict__"  )
 
536
//                              {
 
537
//                              return Py::Dict();
 
538
//                              }
 
539
                        else
 
540
                                {
 
541
                                return getattr_methods( _name );
 
542
                                }
 
543
                        }
 
544
 
 
545
                // turn a name into function object
 
546
                virtual Object getattr_methods( const char *_name )
 
547
                        {
 
548
                        std::string name( _name );
 
549
                        
 
550
                        method_map_t &mm = methods();
 
551
                        
 
552
                        if( name == "__methods__" )
 
553
                                {
 
554
                                List methods;
 
555
                                
 
556
                                for( EXPLICIT_TYPENAME method_map_t::iterator i = mm.begin(); i != mm.end(); ++i )
 
557
                                        methods.append( String( (*i).first ) );
 
558
                                
 
559
                                return methods;
 
560
                                }
 
561
                        
 
562
                        // see if name exists
 
563
                        if( mm.find( name ) == mm.end() )
 
564
                                throw AttributeError( name );
 
565
                        
 
566
                        Tuple self( 2 );
 
567
                        
 
568
                        self[0] = Object( this );
 
569
                        self[1] = String( name );
 
570
                        
 
571
                        MethodDefExt<T> *method_definition = mm[ name ];
 
572
                        
 
573
                        PyObject *func = PyCFunction_New( &method_definition->ext_meth_def, self.ptr() );
 
574
                        
 
575
                        return Object(func, true);
 
576
                        }
 
577
                
 
578
                static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
 
579
                        {
 
580
                        method_map_t &mm = methods();
 
581
                        
 
582
                        MethodDefExt<T> *method_definition = new MethodDefExt<T>
 
583
                        (
 
584
                        name,
 
585
                        function,
 
586
                        method_varargs_call_handler,
 
587
                        doc
 
588
                        );
 
589
                        
 
590
                        mm[std::string( name )] = method_definition;
 
591
                        }
 
592
                
 
593
                static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
 
594
                        {
 
595
                        method_map_t &mm = methods();
 
596
                        
 
597
                        MethodDefExt<T> *method_definition = new MethodDefExt<T>
 
598
                        (
 
599
                        name,
 
600
                        function,
 
601
                        method_keyword_call_handler,
 
602
                        doc
 
603
                        );
 
604
                        
 
605
                        mm[std::string( name )] = method_definition;
 
606
                        }
 
607
                
 
608
        private:
 
609
                static method_map_t &methods(void)
 
610
                        {
 
611
                        static method_map_t *map_of_methods = NULL;
 
612
                        if( map_of_methods == NULL )
 
613
                        map_of_methods = new method_map_t;
 
614
                        
 
615
                        return *map_of_methods;
 
616
                        }
 
617
                
 
618
                static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
 
619
                        {
 
620
                        try
 
621
                                {
 
622
                                Tuple self_and_name_tuple( _self_and_name_tuple );
 
623
                                
 
624
                                PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
 
625
                                T *self = static_cast<T *>( self_in_cobject );
 
626
                                
 
627
                                String name( self_and_name_tuple[1] );
 
628
                                
 
629
                                method_map_t &mm = methods();
 
630
                                MethodDefExt<T> *meth_def = mm[ name ];
 
631
                                if( meth_def == NULL )
 
632
                                        return 0;
 
633
                                
 
634
                                Tuple args( _args );
 
635
 
 
636
                                // _keywords may be NULL so be careful about the way the dict is created
 
637
                                Dict keywords;
 
638
                                if( _keywords != NULL )
 
639
                                        keywords = Dict( _keywords );
 
640
                                
 
641
                                Object result( (self->*meth_def->ext_keyword_function)( args, keywords ) );
 
642
                                
 
643
                                return new_reference_to( result.ptr() );
 
644
                                }
 
645
                        catch( Exception & )
 
646
                                {
 
647
                                return 0;
 
648
                                }
 
649
                        }
 
650
                
 
651
                static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
 
652
                        {
 
653
                        try
 
654
                                {
 
655
                                Tuple self_and_name_tuple( _self_and_name_tuple );
 
656
                                
 
657
                                PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
 
658
                                T *self = static_cast<T *>( self_in_cobject );
 
659
                                
 
660
                                String name( self_and_name_tuple[1] );
 
661
                                
 
662
                                method_map_t &mm = methods();
 
663
                                MethodDefExt<T> *meth_def = mm[ name ];
 
664
                                if( meth_def == NULL )
 
665
                                        return 0;
 
666
                                
 
667
                                Tuple args( _args );
 
668
                                
 
669
                                Object result;
 
670
                                
 
671
                                // TMM: 7Jun'01 - Adding try & catch in case of STL debug-mode exceptions.
 
672
                                #ifdef _STLP_DEBUG
 
673
                                try
 
674
                                        {
 
675
                                        result = (self->*meth_def->ext_varargs_function)( args );
 
676
                                        }
 
677
                                catch (std::__stl_debug_exception)
 
678
                                        {
 
679
                                        // throw cxx::RuntimeError( sErrMsg );
 
680
                                        throw cxx::RuntimeError( "Error message not set yet." );
 
681
                                        }
 
682
                                #else
 
683
                                result = (self->*meth_def->ext_varargs_function)( args );
 
684
                                #endif // _STLP_DEBUG
 
685
                                
 
686
                                return new_reference_to( result.ptr() );
 
687
                                }
 
688
                        catch( Exception & )
 
689
                                {
 
690
                                return 0;
 
691
                                }
 
692
                        }
 
693
                
 
694
                static void extension_object_deallocator ( PyObject* t )
 
695
                        {
 
696
                        delete (T *)( t );
 
697
                        }
 
698
                
 
699
                //
 
700
                // prevent the compiler generating these unwanted functions
 
701
                //
 
702
                explicit PythonExtension( const PythonExtension<T>& other );
 
703
                void operator=( const PythonExtension<T>& rhs );
 
704
                };
 
705
        
 
706
        //
 
707
        // ExtensionObject<T> is an Object that will accept only T's.
 
708
        //
 
709
        template<TEMPLATE_TYPENAME T>
 
710
        class ExtensionObject: public Object
 
711
                {
 
712
        public:
 
713
                
 
714
                explicit ExtensionObject ( PyObject *pyob )
 
715
                        : Object( pyob )
 
716
                        {
 
717
                        validate();
 
718
                        }
 
719
                
 
720
                ExtensionObject( const ExtensionObject<T>& other )
 
721
                        : Object( *other )
 
722
                        {
 
723
                        validate();
 
724
                        }
 
725
                
 
726
                ExtensionObject( const Object& other )
 
727
                        : Object( *other )
 
728
                        {
 
729
                        validate();
 
730
                        }
 
731
                
 
732
                ExtensionObject& operator= ( const Object& rhs )
 
733
                        {
 
734
                        return (*this = *rhs );
 
735
                        }
 
736
                
 
737
                ExtensionObject& operator= ( PyObject* rhsp )
 
738
                        {
 
739
                        if( ptr() == rhsp )
 
740
                        return *this;
 
741
                        set( rhsp );
 
742
                        return *this;
 
743
                        }
 
744
                
 
745
                virtual bool accepts ( PyObject *pyob ) const
 
746
                        {
 
747
                        return ( pyob && T::check( pyob ));
 
748
                        }       
 
749
                
 
750
                //
 
751
                //      Obtain a pointer to the PythonExtension object
 
752
                //
 
753
                T *extensionObject(void)
 
754
                        {
 
755
                        return static_cast<T *>( ptr() );
 
756
                        }
 
757
                };
 
758
        
 
759
        } // Namespace Py
 
760
// End of CXX_Extensions.h
 
761
#endif