source: orange/source/include/pywrapper.hpp @ 10478:81f6da13a14b

Revision 10478:81f6da13a14b, 6.6 KB checked in by Janez Demšar <janez.demsar@…>, 2 years ago (diff)

Added patches for 64-bit build by cgohlke (closes #1114)

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#ifdef _WIN64
63   PyWrapper(const size_t &f) 
64   : pyobject(PyInt_FromSize_t(f)) 
65   {} 
66
67   PyWrapper(const ssize_t &f) 
68    : pyobject(PyInt_FromSsize_t(f)) 
69   {} 
70#endif
71
72  operator PyObject *() const
73    { Py_XINCREF(pyobject);
74      return pyobject; }
75
76  PyWrapper(const PyWrapper &other)
77    : pyobject(other.pyobject)
78    { Py_XINCREF(pyobject); }
79
80  void operator = (const PyWrapper &other)
81    { inplace(other.pyobject);
82    }
83
84  void inplace(PyObject *other)
85    { Py_XINCREF(other);
86      Py_XDECREF(pyobject);
87      pyobject=other;
88    }
89
90  int compare(const PyWrapper &other) const
91    { int cmp=PyObject_Compare(pyobject, other.pyobject);
92      checkForError();
93      return cmp;
94    }
95
96  bool operator < (const PyWrapper &other) const
97    { return compare(other)<0; }
98
99  bool operator <= (const PyWrapper &other) const
100    { return compare(other)<=0; }
101
102  bool operator > (const PyWrapper &other) const
103    { return compare(other)>0; }
104
105  bool operator >= (const PyWrapper &other) const
106    { return compare(other)>=0; }
107
108  bool operator == (const PyWrapper &other) const
109    { return !compare(other); }
110
111
112  PyWrapper operator - () const
113    { if (!pyobject)
114        return PyWrapper();
115
116      return PyWrapper(PyNumber_Negative(pyobject));
117    }
118
119  PyWrapper operator + (const PyWrapper &other) const
120    { if (!pyobject)
121        return PyWrapper(other.pyobject);
122
123      if (!other.pyobject)
124        return PyWrapper(pyobject);
125
126      if (PySequence_Check(pyobject)) 
127        return PyWrapper(PySequence_Concat(pyobject, other.pyobject));
128
129      return PyWrapper(PyNumber_Add(pyobject, other));
130    }
131
132  PyWrapper operator - (const PyWrapper &other) const
133    { if (!pyobject)
134        return other.operator -();
135
136      if (!other.pyobject)
137        return PyWrapper(pyobject);
138
139      return PyWrapper(PyNumber_Subtract(pyobject, other));
140    }
141
142  PyWrapper operator * (const PyWrapper &other) const
143    { if (!pyobject || !other.pyobject)
144        return PyWrapper();
145
146      return PyWrapper(PyNumber_Multiply(pyobject, other));
147    }
148
149  PyWrapper operator / (const PyWrapper &other) const
150    { if (!pyobject || !other.pyobject)
151        return PyWrapper();
152
153      return PyWrapper(PyNumber_Divide(pyobject, other));
154    }
155
156  PyWrapper &operator += (const PyWrapper &other)
157    { if (!pyobject) {
158        inplace(other.pyobject);
159        return *this;
160      }
161
162      if (!other.pyobject)
163        return *this;
164
165      PyObject *res;
166      if (PySequence_Check(pyobject)) 
167        res=PySequence_Concat(pyobject, other.pyobject);
168      else
169        res=PyNumber_Add(pyobject, other);
170
171      inplace(res);
172      checkForError();
173      Py_XDECREF(res);
174      return *this;
175    }
176
177  PyWrapper &operator -= (const PyWrapper &other)
178    { if (!pyobject) {
179        PyWrapper otm=other.operator -();
180        inplace(other.pyobject);
181        return *this;
182      }
183
184      if (!other.pyobject)
185        return *this;
186
187      PyObject *res=PyNumber_Subtract(pyobject, other);
188      inplace(res);
189      Py_XDECREF(res);
190      return *this;
191    }
192
193  PyWrapper &operator *= (const PyWrapper &other)
194    { if (!pyobject || !other.pyobject) {
195        inplace(NULL);
196        return *this;
197      }
198
199      PyObject *res=PyNumber_Multiply(pyobject, other);
200      inplace(res);
201      Py_XDECREF(res);
202      return *this;
203    }
204
205  PyWrapper &operator /= (const PyWrapper &other)
206    { if (!pyobject || !other.pyobject) {
207        inplace(NULL);
208        return *this;
209      }
210
211      PyObject *res=PyNumber_Divide(pyobject, other);
212      inplace(res);
213      Py_XDECREF(res);
214      return *this;
215    }
216
217  PyWrapper &operator ++ ()
218    { if (!pyobject)
219        return *this;
220   
221      PyObject *res=PyNumber_Add(pyobject, PyInt_FromLong(1));
222      inplace(res);
223      Py_XDECREF(res);
224      return *this;
225    }
226
227
228  static void checkForError()
229  {
230    if (PyErr_Occurred())
231        throw pyexception();
232  }
233};
234
235#define UNARY_FUNCTION(name) \
236  inline PyWrapper name(const PyWrapper &x) \
237  { if (!x.pyobject) \
238    throw pyexception("NULL object"); \
239\
240    PyObject *num=PyNumber_Float(x); \
241    if (!num) PyWrapper::checkForError(); \
242    return PyWrapper(num ? PyFloat_FromDouble(name(PyFloat_AsDouble(num))) : NULL); \
243  }
244
245UNARY_FUNCTION(log)
246UNARY_FUNCTION(exp)
247UNARY_FUNCTION(sqrt)
248
249#undef UNARY_FUNCTION
250
251inline PyWrapper abs(const PyWrapper &x)
252{ if (!x.pyobject)
253    throw pyexception("NULL object");
254
255  PyObject *res=PyNumber_Absolute(x);
256  if (!res) PyWrapper::checkForError();
257  return PyWrapper(res);
258}
259
260inline PyWrapper fabs(const PyWrapper &x)
261{ if (!x.pyobject)
262    throw pyexception("NULL object");
263
264  PyObject *res=PyNumber_Absolute(x);
265  if (!res) PyWrapper::checkForError();
266  return PyWrapper(res);
267}
268
269
270inline int convert_to_int (const PyWrapper &x)
271{ if (!x.pyobject)
272    throw pyexception("NULL object");
273
274  PyObject *pyn=PyNumber_Int(x.pyobject);
275  PyWrapper::checkForError();
276
277  return int(PyInt_AsLong(pyn));
278}
279
280inline double convert_to_double (const PyWrapper &x)
281{ if (!x.pyobject)
282    throw pyexception("NULL object");
283
284  PyObject *pyn=PyNumber_Float(x.pyobject);
285  PyWrapper::checkForError();
286
287  return PyFloat_AsDouble(pyn);
288}
289
290// This is defined by Python but then redefined by STLPort
291#undef LONGLONG_MAX
292#undef ULONGLONG_MAX
293
294#endif
Note: See TracBrowser for help on using the repository browser.