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

Revision 6531:57bdc92cd8e9, 6.4 KB checked in by janezd <janez.demsar@…>, 4 years ago (diff) |
---|

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> |

27 | using namespace std; |

28 | |

29 | #include "Python.h" |

30 | |

31 | class PyWrapper { |

32 | public: |

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 | |

235 | UNARY_FUNCTION(log) |

236 | UNARY_FUNCTION(exp) |

237 | UNARY_FUNCTION(sqrt) |

238 | |

239 | #undef UNARY_FUNCTION |

240 | |

241 | inline 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 | |

250 | inline 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 | |

260 | inline 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 | |

270 | inline 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.