~ubuntu-branches/ubuntu/karmic/python-scipy/karmic

« back to all changes in this revision

Viewing changes to Lib/weave/examples/fibonacci_ext.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik
  • Date: 2008-06-16 22:58:01 UTC
  • mfrom: (2.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080616225801-irdhrpcwiocfbcmt
Tags: 0.6.0-12
* The description updated to match the current SciPy (Closes: #489149).
* Standards-Version bumped to 3.8.0 (no action needed)
* Build-Depends: netcdf-dev changed to libnetcdf-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#ifdef __CPLUSPLUS__
2
 
extern "C" {
3
 
#endif
4
 
 
5
 
#pragma warning(disable: 4275)
6
 
#pragma warning(disable: 4101)
7
 
 
8
 
#include "Python.h"
9
 
#include "compile.h"
10
 
#include "frameobject.h"
11
 
#include <complex>
12
 
#include <math.h>
13
 
#include <string>
14
 
#include "scxx/object.h"
15
 
#include "scxx/list.h"
16
 
#include "scxx/tuple.h"
17
 
#include "scxx/dict.h"
18
 
#include <iostream>
19
 
#include <stdio.h>
20
 
#include "numpy/arrayobject.h"
21
 
 
22
 
 
23
 
 
24
 
 
25
 
// global None value for use in functions.
26
 
namespace py {
27
 
object None = object(Py_None);
28
 
}
29
 
 
30
 
char* find_type(PyObject* py_obj)
31
 
{
32
 
    if(py_obj == NULL) return "C NULL value";
33
 
    if(PyCallable_Check(py_obj)) return "callable";
34
 
    if(PyString_Check(py_obj)) return "string";
35
 
    if(PyInt_Check(py_obj)) return "int";
36
 
    if(PyFloat_Check(py_obj)) return "float";
37
 
    if(PyDict_Check(py_obj)) return "dict";
38
 
    if(PyList_Check(py_obj)) return "list";
39
 
    if(PyTuple_Check(py_obj)) return "tuple";
40
 
    if(PyFile_Check(py_obj)) return "file";
41
 
    if(PyModule_Check(py_obj)) return "module";
42
 
 
43
 
    //should probably do more intergation (and thinking) on these.
44
 
    if(PyCallable_Check(py_obj) && PyInstance_Check(py_obj)) return "callable";
45
 
    if(PyInstance_Check(py_obj)) return "instance";
46
 
    if(PyCallable_Check(py_obj)) return "callable";
47
 
    return "unkown type";
48
 
}
49
 
 
50
 
void throw_error(PyObject* exc, const char* msg)
51
 
{
52
 
 //printf("setting python error: %s\n",msg);
53
 
  PyErr_SetString(exc, msg);
54
 
  //printf("throwing error\n");
55
 
  throw 1;
56
 
}
57
 
 
58
 
void handle_bad_type(PyObject* py_obj, const char* good_type, const char* var_name)
59
 
{
60
 
    char msg[500];
61
 
    sprintf(msg,"received '%s' type instead of '%s' for variable '%s'",
62
 
            find_type(py_obj),good_type,var_name);
63
 
    throw_error(PyExc_TypeError,msg);
64
 
}
65
 
 
66
 
void handle_conversion_error(PyObject* py_obj, const char* good_type, const char* var_name)
67
 
{
68
 
    char msg[500];
69
 
    sprintf(msg,"Conversion Error:, received '%s' type instead of '%s' for variable '%s'",
70
 
            find_type(py_obj),good_type,var_name);
71
 
    throw_error(PyExc_TypeError,msg);
72
 
}
73
 
 
74
 
 
75
 
class int_handler
76
 
{
77
 
public:
78
 
    int convert_to_int(PyObject* py_obj, const char* name)
79
 
    {
80
 
        // Incref occurs even if conversion fails so that
81
 
        // the decref in cleanup_code has a matching incref.
82
 
        
83
 
        if (!py_obj || !PyInt_Check(py_obj))
84
 
            handle_conversion_error(py_obj,"int", name);
85
 
        return (int) PyInt_AsLong(py_obj);
86
 
    }
87
 
 
88
 
    int py_to_int(PyObject* py_obj, const char* name)
89
 
    {
90
 
        // !! Pretty sure INCREF should only be called on success since
91
 
        // !! py_to_xxx is used by the user -- not the code generator.
92
 
        if (!py_obj || !PyInt_Check(py_obj))
93
 
            handle_bad_type(py_obj,"int", name);
94
 
        
95
 
        return (int) PyInt_AsLong(py_obj);
96
 
    }
97
 
};
98
 
 
99
 
int_handler x__int_handler = int_handler();
100
 
#define convert_to_int(py_obj,name) \
101
 
        x__int_handler.convert_to_int(py_obj,name)
102
 
#define py_to_int(py_obj,name) \
103
 
        x__int_handler.py_to_int(py_obj,name)
104
 
 
105
 
 
106
 
PyObject* int_to_py(PyObject* obj)
107
 
{
108
 
    return (PyObject*) obj;
109
 
}
110
 
 
111
 
 
112
 
class float_handler
113
 
{
114
 
public:
115
 
    double convert_to_float(PyObject* py_obj, const char* name)
116
 
    {
117
 
        // Incref occurs even if conversion fails so that
118
 
        // the decref in cleanup_code has a matching incref.
119
 
        
120
 
        if (!py_obj || !PyFloat_Check(py_obj))
121
 
            handle_conversion_error(py_obj,"float", name);
122
 
        return PyFloat_AsDouble(py_obj);
123
 
    }
124
 
 
125
 
    double py_to_float(PyObject* py_obj, const char* name)
126
 
    {
127
 
        // !! Pretty sure INCREF should only be called on success since
128
 
        // !! py_to_xxx is used by the user -- not the code generator.
129
 
        if (!py_obj || !PyFloat_Check(py_obj))
130
 
            handle_bad_type(py_obj,"float", name);
131
 
        
132
 
        return PyFloat_AsDouble(py_obj);
133
 
    }
134
 
};
135
 
 
136
 
float_handler x__float_handler = float_handler();
137
 
#define convert_to_float(py_obj,name) \
138
 
        x__float_handler.convert_to_float(py_obj,name)
139
 
#define py_to_float(py_obj,name) \
140
 
        x__float_handler.py_to_float(py_obj,name)
141
 
 
142
 
 
143
 
PyObject* float_to_py(PyObject* obj)
144
 
{
145
 
    return (PyObject*) obj;
146
 
}
147
 
 
148
 
 
149
 
class complex_handler
150
 
{
151
 
public:
152
 
    std::complex<double> convert_to_complex(PyObject* py_obj, const char* name)
153
 
    {
154
 
        // Incref occurs even if conversion fails so that
155
 
        // the decref in cleanup_code has a matching incref.
156
 
        
157
 
        if (!py_obj || !PyComplex_Check(py_obj))
158
 
            handle_conversion_error(py_obj,"complex", name);
159
 
        return std::complex<double>(PyComplex_RealAsDouble(py_obj),PyComplex_ImagAsDouble(py_obj));
160
 
    }
161
 
 
162
 
    std::complex<double> py_to_complex(PyObject* py_obj, const char* name)
163
 
    {
164
 
        // !! Pretty sure INCREF should only be called on success since
165
 
        // !! py_to_xxx is used by the user -- not the code generator.
166
 
        if (!py_obj || !PyComplex_Check(py_obj))
167
 
            handle_bad_type(py_obj,"complex", name);
168
 
        
169
 
        return std::complex<double>(PyComplex_RealAsDouble(py_obj),PyComplex_ImagAsDouble(py_obj));
170
 
    }
171
 
};
172
 
 
173
 
complex_handler x__complex_handler = complex_handler();
174
 
#define convert_to_complex(py_obj,name) \
175
 
        x__complex_handler.convert_to_complex(py_obj,name)
176
 
#define py_to_complex(py_obj,name) \
177
 
        x__complex_handler.py_to_complex(py_obj,name)
178
 
 
179
 
 
180
 
PyObject* complex_to_py(PyObject* obj)
181
 
{
182
 
    return (PyObject*) obj;
183
 
}
184
 
 
185
 
 
186
 
class unicode_handler
187
 
{
188
 
public:
189
 
    Py_UNICODE* convert_to_unicode(PyObject* py_obj, const char* name)
190
 
    {
191
 
        // Incref occurs even if conversion fails so that
192
 
        // the decref in cleanup_code has a matching incref.
193
 
        Py_XINCREF(py_obj);
194
 
        if (!py_obj || !PyUnicode_Check(py_obj))
195
 
            handle_conversion_error(py_obj,"unicode", name);
196
 
        return PyUnicode_AS_UNICODE(py_obj);
197
 
    }
198
 
 
199
 
    Py_UNICODE* py_to_unicode(PyObject* py_obj, const char* name)
200
 
    {
201
 
        // !! Pretty sure INCREF should only be called on success since
202
 
        // !! py_to_xxx is used by the user -- not the code generator.
203
 
        if (!py_obj || !PyUnicode_Check(py_obj))
204
 
            handle_bad_type(py_obj,"unicode", name);
205
 
        Py_XINCREF(py_obj);
206
 
        return PyUnicode_AS_UNICODE(py_obj);
207
 
    }
208
 
};
209
 
 
210
 
unicode_handler x__unicode_handler = unicode_handler();
211
 
#define convert_to_unicode(py_obj,name) \
212
 
        x__unicode_handler.convert_to_unicode(py_obj,name)
213
 
#define py_to_unicode(py_obj,name) \
214
 
        x__unicode_handler.py_to_unicode(py_obj,name)
215
 
 
216
 
 
217
 
PyObject* unicode_to_py(PyObject* obj)
218
 
{
219
 
    return (PyObject*) obj;
220
 
}
221
 
 
222
 
 
223
 
class string_handler
224
 
{
225
 
public:
226
 
    std::string convert_to_string(PyObject* py_obj, const char* name)
227
 
    {
228
 
        // Incref occurs even if conversion fails so that
229
 
        // the decref in cleanup_code has a matching incref.
230
 
        Py_XINCREF(py_obj);
231
 
        if (!py_obj || !PyString_Check(py_obj))
232
 
            handle_conversion_error(py_obj,"string", name);
233
 
        return std::string(PyString_AsString(py_obj));
234
 
    }
235
 
 
236
 
    std::string py_to_string(PyObject* py_obj, const char* name)
237
 
    {
238
 
        // !! Pretty sure INCREF should only be called on success since
239
 
        // !! py_to_xxx is used by the user -- not the code generator.
240
 
        if (!py_obj || !PyString_Check(py_obj))
241
 
            handle_bad_type(py_obj,"string", name);
242
 
        Py_XINCREF(py_obj);
243
 
        return std::string(PyString_AsString(py_obj));
244
 
    }
245
 
};
246
 
 
247
 
string_handler x__string_handler = string_handler();
248
 
#define convert_to_string(py_obj,name) \
249
 
        x__string_handler.convert_to_string(py_obj,name)
250
 
#define py_to_string(py_obj,name) \
251
 
        x__string_handler.py_to_string(py_obj,name)
252
 
 
253
 
 
254
 
               PyObject* string_to_py(std::string s)
255
 
               {
256
 
                   return PyString_FromString(s.c_str());
257
 
               }
258
 
               
259
 
class list_handler
260
 
{
261
 
public:
262
 
    py::list convert_to_list(PyObject* py_obj, const char* name)
263
 
    {
264
 
        // Incref occurs even if conversion fails so that
265
 
        // the decref in cleanup_code has a matching incref.
266
 
        
267
 
        if (!py_obj || !PyList_Check(py_obj))
268
 
            handle_conversion_error(py_obj,"list", name);
269
 
        return py::list(py_obj);
270
 
    }
271
 
 
272
 
    py::list py_to_list(PyObject* py_obj, const char* name)
273
 
    {
274
 
        // !! Pretty sure INCREF should only be called on success since
275
 
        // !! py_to_xxx is used by the user -- not the code generator.
276
 
        if (!py_obj || !PyList_Check(py_obj))
277
 
            handle_bad_type(py_obj,"list", name);
278
 
        
279
 
        return py::list(py_obj);
280
 
    }
281
 
};
282
 
 
283
 
list_handler x__list_handler = list_handler();
284
 
#define convert_to_list(py_obj,name) \
285
 
        x__list_handler.convert_to_list(py_obj,name)
286
 
#define py_to_list(py_obj,name) \
287
 
        x__list_handler.py_to_list(py_obj,name)
288
 
 
289
 
 
290
 
PyObject* list_to_py(PyObject* obj)
291
 
{
292
 
    return (PyObject*) obj;
293
 
}
294
 
 
295
 
 
296
 
class dict_handler
297
 
{
298
 
public:
299
 
    py::dict convert_to_dict(PyObject* py_obj, const char* name)
300
 
    {
301
 
        // Incref occurs even if conversion fails so that
302
 
        // the decref in cleanup_code has a matching incref.
303
 
        
304
 
        if (!py_obj || !PyDict_Check(py_obj))
305
 
            handle_conversion_error(py_obj,"dict", name);
306
 
        return py::dict(py_obj);
307
 
    }
308
 
 
309
 
    py::dict py_to_dict(PyObject* py_obj, const char* name)
310
 
    {
311
 
        // !! Pretty sure INCREF should only be called on success since
312
 
        // !! py_to_xxx is used by the user -- not the code generator.
313
 
        if (!py_obj || !PyDict_Check(py_obj))
314
 
            handle_bad_type(py_obj,"dict", name);
315
 
        
316
 
        return py::dict(py_obj);
317
 
    }
318
 
};
319
 
 
320
 
dict_handler x__dict_handler = dict_handler();
321
 
#define convert_to_dict(py_obj,name) \
322
 
        x__dict_handler.convert_to_dict(py_obj,name)
323
 
#define py_to_dict(py_obj,name) \
324
 
        x__dict_handler.py_to_dict(py_obj,name)
325
 
 
326
 
 
327
 
PyObject* dict_to_py(PyObject* obj)
328
 
{
329
 
    return (PyObject*) obj;
330
 
}
331
 
 
332
 
 
333
 
class tuple_handler
334
 
{
335
 
public:
336
 
    py::tuple convert_to_tuple(PyObject* py_obj, const char* name)
337
 
    {
338
 
        // Incref occurs even if conversion fails so that
339
 
        // the decref in cleanup_code has a matching incref.
340
 
        
341
 
        if (!py_obj || !PyTuple_Check(py_obj))
342
 
            handle_conversion_error(py_obj,"tuple", name);
343
 
        return py::tuple(py_obj);
344
 
    }
345
 
 
346
 
    py::tuple py_to_tuple(PyObject* py_obj, const char* name)
347
 
    {
348
 
        // !! Pretty sure INCREF should only be called on success since
349
 
        // !! py_to_xxx is used by the user -- not the code generator.
350
 
        if (!py_obj || !PyTuple_Check(py_obj))
351
 
            handle_bad_type(py_obj,"tuple", name);
352
 
        
353
 
        return py::tuple(py_obj);
354
 
    }
355
 
};
356
 
 
357
 
tuple_handler x__tuple_handler = tuple_handler();
358
 
#define convert_to_tuple(py_obj,name) \
359
 
        x__tuple_handler.convert_to_tuple(py_obj,name)
360
 
#define py_to_tuple(py_obj,name) \
361
 
        x__tuple_handler.py_to_tuple(py_obj,name)
362
 
 
363
 
 
364
 
PyObject* tuple_to_py(PyObject* obj)
365
 
{
366
 
    return (PyObject*) obj;
367
 
}
368
 
 
369
 
 
370
 
class file_handler
371
 
{
372
 
public:
373
 
    FILE* convert_to_file(PyObject* py_obj, const char* name)
374
 
    {
375
 
        // Incref occurs even if conversion fails so that
376
 
        // the decref in cleanup_code has a matching incref.
377
 
        Py_XINCREF(py_obj);
378
 
        if (!py_obj || !PyFile_Check(py_obj))
379
 
            handle_conversion_error(py_obj,"file", name);
380
 
        return PyFile_AsFile(py_obj);
381
 
    }
382
 
 
383
 
    FILE* py_to_file(PyObject* py_obj, const char* name)
384
 
    {
385
 
        // !! Pretty sure INCREF should only be called on success since
386
 
        // !! py_to_xxx is used by the user -- not the code generator.
387
 
        if (!py_obj || !PyFile_Check(py_obj))
388
 
            handle_bad_type(py_obj,"file", name);
389
 
        Py_XINCREF(py_obj);
390
 
        return PyFile_AsFile(py_obj);
391
 
    }
392
 
};
393
 
 
394
 
file_handler x__file_handler = file_handler();
395
 
#define convert_to_file(py_obj,name) \
396
 
        x__file_handler.convert_to_file(py_obj,name)
397
 
#define py_to_file(py_obj,name) \
398
 
        x__file_handler.py_to_file(py_obj,name)
399
 
 
400
 
 
401
 
               PyObject* file_to_py(FILE* file, char* name, char* mode)
402
 
               {
403
 
                   PyObject* py_obj = NULL;
404
 
                   //extern int fclose(FILE *);
405
 
                   return (PyObject*) PyFile_FromFile(file, name, mode, fclose);
406
 
               }
407
 
               
408
 
class instance_handler
409
 
{
410
 
public:
411
 
    py::object convert_to_instance(PyObject* py_obj, const char* name)
412
 
    {
413
 
        // Incref occurs even if conversion fails so that
414
 
        // the decref in cleanup_code has a matching incref.
415
 
        
416
 
        if (!py_obj || !PyInstance_Check(py_obj))
417
 
            handle_conversion_error(py_obj,"instance", name);
418
 
        return py::object(py_obj);
419
 
    }
420
 
 
421
 
    py::object py_to_instance(PyObject* py_obj, const char* name)
422
 
    {
423
 
        // !! Pretty sure INCREF should only be called on success since
424
 
        // !! py_to_xxx is used by the user -- not the code generator.
425
 
        if (!py_obj || !PyInstance_Check(py_obj))
426
 
            handle_bad_type(py_obj,"instance", name);
427
 
        
428
 
        return py::object(py_obj);
429
 
    }
430
 
};
431
 
 
432
 
instance_handler x__instance_handler = instance_handler();
433
 
#define convert_to_instance(py_obj,name) \
434
 
        x__instance_handler.convert_to_instance(py_obj,name)
435
 
#define py_to_instance(py_obj,name) \
436
 
        x__instance_handler.py_to_instance(py_obj,name)
437
 
 
438
 
 
439
 
PyObject* instance_to_py(PyObject* obj)
440
 
{
441
 
    return (PyObject*) obj;
442
 
}
443
 
 
444
 
 
445
 
class numpy_size_handler
446
 
{
447
 
public:
448
 
    void conversion_numpy_check_size(PyArrayObject* arr_obj, int Ndims,
449
 
                                     const char* name)
450
 
    {
451
 
        if (arr_obj->nd != Ndims)
452
 
        {
453
 
            char msg[500];
454
 
            sprintf(msg,"Conversion Error: received '%d' dimensional array instead of '%d' dimensional array for variable '%s'",
455
 
                    arr_obj->nd,Ndims,name);
456
 
            throw_error(PyExc_TypeError,msg);
457
 
        }
458
 
    }
459
 
 
460
 
    void numpy_check_size(PyArrayObject* arr_obj, int Ndims, const char* name)
461
 
    {
462
 
        if (arr_obj->nd != Ndims)
463
 
        {
464
 
            char msg[500];
465
 
            sprintf(msg,"received '%d' dimensional array instead of '%d' dimensional array for variable '%s'",
466
 
                    arr_obj->nd,Ndims,name);
467
 
            throw_error(PyExc_TypeError,msg);
468
 
        }
469
 
    }
470
 
};
471
 
 
472
 
numpy_size_handler x__numpy_size_handler = numpy_size_handler();
473
 
#define conversion_numpy_check_size x__numpy_size_handler.conversion_numpy_check_size
474
 
#define numpy_check_size x__numpy_size_handler.numpy_check_size
475
 
 
476
 
 
477
 
class numpy_type_handler
478
 
{
479
 
public:
480
 
    void conversion_numpy_check_type(PyArrayObject* arr_obj, int numeric_type,
481
 
                                     const char* name)
482
 
    {
483
 
        // Make sure input has correct numeric type.
484
 
        int arr_type = arr_obj->descr->type_num;
485
 
        if (PyTypeNum_ISEXTENDED(numeric_type))
486
 
        {
487
 
        char msg[80];
488
 
        sprintf(msg, "Conversion Error: extended types not supported for variable '%s'",
489
 
                name);
490
 
        throw_error(PyExc_TypeError, msg);
491
 
        }
492
 
        if (!PyArray_EquivTypenums(arr_type, numeric_type))
493
 
        {
494
 
 
495
 
        char* type_names[23] = {"bool", "byte", "ubyte","short", "ushort",
496
 
                                "int", "uint", "long", "ulong", "longlong", "ulonglong",
497
 
                                "float", "double", "longdouble", "cfloat", "cdouble",
498
 
                                "clongdouble", "object", "string", "unicode", "void", "ntype",
499
 
                                "unknown"};
500
 
        char msg[500];
501
 
        sprintf(msg,"Conversion Error: received '%s' typed array instead of '%s' typed array for variable '%s'",
502
 
                type_names[arr_type],type_names[numeric_type],name);
503
 
        throw_error(PyExc_TypeError,msg);
504
 
        }
505
 
    }
506
 
 
507
 
    void numpy_check_type(PyArrayObject* arr_obj, int numeric_type, const char* name)
508
 
    {
509
 
        // Make sure input has correct numeric type.
510
 
        int arr_type = arr_obj->descr->type_num;
511
 
        if (PyTypeNum_ISEXTENDED(numeric_type))
512
 
        {
513
 
        char msg[80];
514
 
        sprintf(msg, "Conversion Error: extended types not supported for variable '%s'",
515
 
                name);
516
 
        throw_error(PyExc_TypeError, msg);
517
 
        }
518
 
        if (!PyArray_EquivTypenums(arr_type, numeric_type))
519
 
        {
520
 
            char* type_names[23] = {"bool", "byte", "ubyte","short", "ushort",
521
 
                                    "int", "uint", "long", "ulong", "longlong", "ulonglong",
522
 
                                    "float", "double", "longdouble", "cfloat", "cdouble",
523
 
                                    "clongdouble", "object", "string", "unicode", "void", "ntype",
524
 
                                    "unknown"};
525
 
            char msg[500];
526
 
            sprintf(msg,"received '%s' typed array instead of '%s' typed array for variable '%s'",
527
 
                    type_names[arr_type],type_names[numeric_type],name);
528
 
            throw_error(PyExc_TypeError,msg);
529
 
        }
530
 
    }
531
 
};
532
 
 
533
 
numpy_type_handler x__numpy_type_handler = numpy_type_handler();
534
 
#define conversion_numpy_check_type x__numpy_type_handler.conversion_numpy_check_type
535
 
#define numpy_check_type x__numpy_type_handler.numpy_check_type
536
 
 
537
 
 
538
 
class numpy_handler
539
 
{
540
 
public:
541
 
    PyArrayObject* convert_to_numpy(PyObject* py_obj, const char* name)
542
 
    {
543
 
        // Incref occurs even if conversion fails so that
544
 
        // the decref in cleanup_code has a matching incref.
545
 
        Py_XINCREF(py_obj);
546
 
        if (!py_obj || !PyArray_Check(py_obj))
547
 
            handle_conversion_error(py_obj,"numpy", name);
548
 
        return (PyArrayObject*) py_obj;
549
 
    }
550
 
 
551
 
    PyArrayObject* py_to_numpy(PyObject* py_obj, const char* name)
552
 
    {
553
 
        // !! Pretty sure INCREF should only be called on success since
554
 
        // !! py_to_xxx is used by the user -- not the code generator.
555
 
        if (!py_obj || !PyArray_Check(py_obj))
556
 
            handle_bad_type(py_obj,"numpy", name);
557
 
        Py_XINCREF(py_obj);
558
 
        return (PyArrayObject*) py_obj;
559
 
    }
560
 
};
561
 
 
562
 
numpy_handler x__numpy_handler = numpy_handler();
563
 
#define convert_to_numpy(py_obj,name) \
564
 
        x__numpy_handler.convert_to_numpy(py_obj,name)
565
 
#define py_to_numpy(py_obj,name) \
566
 
        x__numpy_handler.py_to_numpy(py_obj,name)
567
 
 
568
 
 
569
 
PyObject* numpy_to_py(PyObject* obj)
570
 
{
571
 
    return (PyObject*) obj;
572
 
}
573
 
 
574
 
 
575
 
class catchall_handler
576
 
{
577
 
public:
578
 
    py::object convert_to_catchall(PyObject* py_obj, const char* name)
579
 
    {
580
 
        // Incref occurs even if conversion fails so that
581
 
        // the decref in cleanup_code has a matching incref.
582
 
        
583
 
        if (!py_obj || !(py_obj))
584
 
            handle_conversion_error(py_obj,"catchall", name);
585
 
        return py::object(py_obj);
586
 
    }
587
 
 
588
 
    py::object py_to_catchall(PyObject* py_obj, const char* name)
589
 
    {
590
 
        // !! Pretty sure INCREF should only be called on success since
591
 
        // !! py_to_xxx is used by the user -- not the code generator.
592
 
        if (!py_obj || !(py_obj))
593
 
            handle_bad_type(py_obj,"catchall", name);
594
 
        
595
 
        return py::object(py_obj);
596
 
    }
597
 
};
598
 
 
599
 
catchall_handler x__catchall_handler = catchall_handler();
600
 
#define convert_to_catchall(py_obj,name) \
601
 
        x__catchall_handler.convert_to_catchall(py_obj,name)
602
 
#define py_to_catchall(py_obj,name) \
603
 
        x__catchall_handler.py_to_catchall(py_obj,name)
604
 
 
605
 
 
606
 
PyObject* catchall_to_py(PyObject* obj)
607
 
{
608
 
    return (PyObject*) obj;
609
 
}
610
 
 
611
 
 
612
 
                   int fib1(int a)
613
 
                   {
614
 
                       if(a <= 2)
615
 
                           return 1;
616
 
                       else
617
 
                           return fib1(a-2) + fib1(a-1);
618
 
                   }
619
 
               
620
 
                    int fib2( int a )
621
 
                    {
622
 
                        int last, next_to_last, result;
623
 
 
624
 
                        if( a <= 2 )
625
 
                            return 1;
626
 
                        last = next_to_last = 1;
627
 
                        for(int i = 2; i < a; i++ )
628
 
                        {
629
 
                            result = last + next_to_last;
630
 
                            next_to_last = last;
631
 
                            last = result;
632
 
                        }
633
 
 
634
 
                        return result;
635
 
                    }
636
 
               
637
 
 
638
 
static PyObject* c_fib1(PyObject*self, PyObject* args, PyObject* kywds)
639
 
{
640
 
    py::object return_val;
641
 
    int exception_occured = 0;
642
 
    PyObject *py_local_dict = NULL;
643
 
    static char *kwlist[] = {"a","local_dict", NULL};
644
 
    PyObject *py_a;
645
 
    int a_used;
646
 
    py_a = NULL;
647
 
    a_used = 0;
648
 
    
649
 
    if(!PyArg_ParseTupleAndKeywords(args,kywds,"O|O:c_fib1",kwlist,&py_a, &py_local_dict))
650
 
       return NULL;
651
 
    try                              
652
 
    {                                
653
 
        py_a = py_a;
654
 
        int a = convert_to_int(py_a,"a");
655
 
        a_used = 1;
656
 
        /*<function call here>*/     
657
 
        
658
 
                           return_val = fib1(a);
659
 
        if(py_local_dict)                                  
660
 
        {                                                  
661
 
            py::dict local_dict = py::dict(py_local_dict); 
662
 
        }                                                  
663
 
    
664
 
    }                                
665
 
    catch(...)                       
666
 
    {                                
667
 
        return_val =  py::object();      
668
 
        exception_occured = 1;       
669
 
    }                                
670
 
    /*cleanup code*/                     
671
 
    if(!(PyObject*)return_val && !exception_occured)
672
 
    {
673
 
                                  
674
 
        return_val = Py_None;            
675
 
    }
676
 
                                  
677
 
    return return_val.disown();           
678
 
}                                
679
 
static PyObject* c_fib2(PyObject*self, PyObject* args, PyObject* kywds)
680
 
{
681
 
    py::object return_val;
682
 
    int exception_occured = 0;
683
 
    PyObject *py_local_dict = NULL;
684
 
    static char *kwlist[] = {"a","local_dict", NULL};
685
 
    PyObject *py_a;
686
 
    int a_used;
687
 
    py_a = NULL;
688
 
    a_used = 0;
689
 
    
690
 
    if(!PyArg_ParseTupleAndKeywords(args,kywds,"O|O:c_fib2",kwlist,&py_a, &py_local_dict))
691
 
       return NULL;
692
 
    try                              
693
 
    {                                
694
 
        py_a = py_a;
695
 
        int a = convert_to_int(py_a,"a");
696
 
        a_used = 1;
697
 
        /*<function call here>*/     
698
 
        
699
 
                           return_val = fib2(a);
700
 
        if(py_local_dict)                                  
701
 
        {                                                  
702
 
            py::dict local_dict = py::dict(py_local_dict); 
703
 
        }                                                  
704
 
    
705
 
    }                                
706
 
    catch(...)                       
707
 
    {                                
708
 
        return_val =  py::object();      
709
 
        exception_occured = 1;       
710
 
    }                                
711
 
    /*cleanup code*/                     
712
 
    if(!(PyObject*)return_val && !exception_occured)
713
 
    {
714
 
                                  
715
 
        return_val = Py_None;            
716
 
    }
717
 
                                  
718
 
    return return_val.disown();           
719
 
}                                
720
 
 
721
 
 
722
 
static PyMethodDef compiled_methods[] = 
723
 
{
724
 
    {"c_fib1",(PyCFunction)c_fib1 , METH_VARARGS|METH_KEYWORDS},
725
 
    {"c_fib2",(PyCFunction)c_fib2 , METH_VARARGS|METH_KEYWORDS},
726
 
    {NULL,      NULL}        /* Sentinel */
727
 
};
728
 
 
729
 
PyMODINIT_FUNC initfibonacci_ext(void)
730
 
{
731
 
    
732
 
    Py_Initialize();
733
 
    import_array();
734
 
    PyImport_ImportModule("numpy");
735
 
    (void) Py_InitModule("fibonacci_ext", compiled_methods);
736
 
}
737
 
 
738
 
#ifdef __CPLUSCPLUS__
739
 
}
740
 
#endif