source: orange/source/include/pywrapper.hpp @ 6531:57bdc92cd8e9

Revision 6531:57bdc92cd8e9, 6.4 KB checked in by janezd <janez.demsar@…>, 4 years ago (diff)
  • changed licenses to GPL 3.0
Line 
1/*
2    This file is part of Orange.
3   
4    Copyright 1996-2010 Faculty of Computer and Information Science, University of Ljubljana
5    Contact: janez.demsar@fri.uni-lj.si
6
7    Orange is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Orange is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Orange.  If not, see <http://www.gnu.org/licenses/>.
19*/
20
21
22#ifndef __PYWRAPPER_HPP
23#define __PYWRAPPER_HPP
24
25#include <math.h>
26#include <exception>
27using namespace std;
28
29#include "Python.h"
30
31class PyWrapper {
32public:
33  PyObject *pyobject;
34
35  PyWrapper(PyObject *pyo = NULL)
36    : pyobject(pyo)
37    { Py_XINCREF(pyobject); }
38
39  ~PyWrapper()
40    { Py_XDECREF(pyobject); }
41
42  PyWrapper(const double &f)
43    : pyobject(PyFloat_FromDouble(f))
44    {}
45
46  PyWrapper(const long &f)
47    : pyobject(PyInt_FromLong(f))
48    {}
49
50  PyWrapper(const unsigned long &f)
51    : pyobject(PyInt_FromLong(f))
52    {}
53
54  PyWrapper(const unsigned int &f)
55    : pyobject(PyInt_FromLong(f))
56    {}
57
58  PyWrapper(const int &f)
59    : pyobject(PyInt_FromLong(f))
60    {}
61
62  operator PyObject *() const
63    { Py_XINCREF(pyobject);
64      return pyobject; }
65
66  PyWrapper(const PyWrapper &other)
67    : pyobject(other.pyobject)
68    { Py_XINCREF(pyobject); }
69
70  void operator = (const PyWrapper &other)
71    { inplace(other.pyobject);
72    }
73
74  void inplace(PyObject *other)
75    { Py_XINCREF(other);
76      Py_XDECREF(pyobject);
77      pyobject=other;
78    }
79
80  int compare(const PyWrapper &other) const
81    { int cmp=PyObject_Compare(pyobject, other.pyobject);
82      checkForError();
83      return cmp;
84    }
85
86  bool operator < (const PyWrapper &other) const
87    { return compare(other)<0; }
88
89  bool operator <= (const PyWrapper &other) const
90    { return compare(other)<=0; }
91
92  bool operator > (const PyWrapper &other) const
93    { return compare(other)>0; }
94
95  bool operator >= (const PyWrapper &other) const
96    { return compare(other)>=0; }
97
98  bool operator == (const PyWrapper &other) const
99    { return !compare(other); }
100
101
102  PyWrapper operator - () const
103    { if (!pyobject)
104        return PyWrapper();
105
106      return PyWrapper(PyNumber_Negative(pyobject));
107    }
108
109  PyWrapper operator + (const PyWrapper &other) const
110    { if (!pyobject)
111        return PyWrapper(other.pyobject);
112
113      if (!other.pyobject)
114        return PyWrapper(pyobject);
115
116      if (PySequence_Check(pyobject)) 
117        return PyWrapper(PySequence_Concat(pyobject, other.pyobject));
118
119      return PyWrapper(PyNumber_Add(pyobject, other));
120    }
121
122  PyWrapper operator - (const PyWrapper &other) const
123    { if (!pyobject)
124        return other.operator -();
125
126      if (!other.pyobject)
127        return PyWrapper(pyobject);
128
129      return PyWrapper(PyNumber_Subtract(pyobject, other));
130    }
131
132  PyWrapper operator * (const PyWrapper &other) const
133    { if (!pyobject || !other.pyobject)
134        return PyWrapper();
135
136      return PyWrapper(PyNumber_Multiply(pyobject, other));
137    }
138
139  PyWrapper operator / (const PyWrapper &other) const
140    { if (!pyobject || !other.pyobject)
141        return PyWrapper();
142
143      return PyWrapper(PyNumber_Divide(pyobject, other));
144    }
145
146  PyWrapper &operator += (const PyWrapper &other)
147    { if (!pyobject) {
148        inplace(other.pyobject);
149        return *this;
150      }
151
152      if (!other.pyobject)
153        return *this;
154
155      PyObject *res;
156      if (PySequence_Check(pyobject)) 
157        res=PySequence_Concat(pyobject, other.pyobject);
158      else
159        res=PyNumber_Add(pyobject, other);
160
161      inplace(res);
162      checkForError();
163      Py_XDECREF(res);
164      return *this;
165    }
166
167  PyWrapper &operator -= (const PyWrapper &other)
168    { if (!pyobject) {
169        PyWrapper otm=other.operator -();
170        inplace(other.pyobject);
171        return *this;
172      }
173
174      if (!other.pyobject)
175        return *this;
176
177      PyObject *res=PyNumber_Subtract(pyobject, other);
178      inplace(res);
179      Py_XDECREF(res);
180      return *this;
181    }
182
183  PyWrapper &operator *= (const PyWrapper &other)
184    { if (!pyobject || !other.pyobject) {
185        inplace(NULL);
186        return *this;
187      }
188
189      PyObject *res=PyNumber_Multiply(pyobject, other);
190      inplace(res);
191      Py_XDECREF(res);
192      return *this;
193    }
194
195  PyWrapper &operator /= (const PyWrapper &other)
196    { if (!pyobject || !other.pyobject) {
197        inplace(NULL);
198        return *this;
199      }
200
201      PyObject *res=PyNumber_Divide(pyobject, other);
202      inplace(res);
203      Py_XDECREF(res);
204      return *this;
205    }
206
207  PyWrapper &operator ++ ()
208    { if (!pyobject)
209        return *this;
210   
211      PyObject *res=PyNumber_Add(pyobject, PyInt_FromLong(1));
212      inplace(res);
213      Py_XDECREF(res);
214      return *this;
215    }
216
217
218  static void checkForError()
219  {
220    if (PyErr_Occurred())
221        throw pyexception();
222  }
223};
224
225#define UNARY_FUNCTION(name) \
226  inline PyWrapper name(const PyWrapper &x) \
227  { if (!x.pyobject) \
228    throw pyexception("NULL object"); \
229\
230    PyObject *num=PyNumber_Float(x); \
231    if (!num) PyWrapper::checkForError(); \
232    return PyWrapper(num ? PyFloat_FromDouble(name(PyFloat_AsDouble(num))) : NULL); \
233  }
234
235UNARY_FUNCTION(log)
236UNARY_FUNCTION(exp)
237UNARY_FUNCTION(sqrt)
238
239#undef UNARY_FUNCTION
240
241inline PyWrapper abs(const PyWrapper &x)
242{ if (!x.pyobject)
243    throw pyexception("NULL object");
244
245  PyObject *res=PyNumber_Absolute(x);
246  if (!res) PyWrapper::checkForError();
247  return PyWrapper(res);
248}
249
250inline PyWrapper fabs(const PyWrapper &x)
251{ if (!x.pyobject)
252    throw pyexception("NULL object");
253
254  PyObject *res=PyNumber_Absolute(x);
255  if (!res) PyWrapper::checkForError();
256  return PyWrapper(res);
257}
258
259
260inline int convert_to_int (const PyWrapper &x)
261{ if (!x.pyobject)
262    throw pyexception("NULL object");
263
264  PyObject *pyn=PyNumber_Int(x.pyobject);
265  PyWrapper::checkForError();
266
267  return int(PyInt_AsLong(pyn));
268}
269
270inline double convert_to_double (const PyWrapper &x)
271{ if (!x.pyobject)
272    throw pyexception("NULL object");
273
274  PyObject *pyn=PyNumber_Float(x.pyobject);
275  PyWrapper::checkForError();
276
277  return PyFloat_AsDouble(pyn);
278}
279
280// This is defined by Python but then redefined by STLPort
281#undef LONGLONG_MAX
282#undef ULONGLONG_MAX
283
284#endif
Note: See TracBrowser for help on using the repository browser.