[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

python_utility.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 2009 by Ullrich Koethe and Hans Meine */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_PYTHON_UTILITY_HXX
37 #define VIGRA_PYTHON_UTILITY_HXX
38 
39 #include <Python.h>
40 #include <algorithm>
41 #include "vigra/error.hxx"
42 #include "vigra/tinyvector.hxx"
43 
44 
45 namespace vigra {
46 
47 template <class PYOBJECT_PTR>
48 void pythonToCppException(PYOBJECT_PTR obj)
49 {
50  if(obj != 0)
51  return;
52  PyObject * type, * value, * trace;
53  PyErr_Fetch(&type, &value, &trace);
54  if(type == 0)
55  return;
56  std::string message(((PyTypeObject *)type)->tp_name);
57  if(PyString_Check(value))
58  {
59  message += std::string(": ") + PyString_AS_STRING(value);
60  }
61 
62  Py_XDECREF(type);
63  Py_XDECREF(value);
64  Py_XDECREF(trace);
65  throw std::runtime_error(message.c_str());
66 }
67 
68 class python_ptr
69 {
70 private:
71  PyObject * ptr_;
72 
73 public:
74 
75  typedef PyObject element_type;
76  typedef PyObject value_type;
77  typedef PyObject * pointer;
78  typedef PyObject & reference;
79 
80  enum refcount_policy { increment_count, borrowed_reference = increment_count,
81  keep_count, new_reference = keep_count };
82 
83  explicit python_ptr(pointer p = 0, refcount_policy rp = increment_count)
84  : ptr_( p )
85  {
86  if(rp == increment_count)
87  {
88  Py_XINCREF(ptr_);
89  }
90  }
91 
92  python_ptr(python_ptr const & p)
93  : ptr_(p.ptr_)
94  {
95  Py_XINCREF(ptr_);
96  }
97 
98  python_ptr & operator=(pointer p)
99  {
100  reset(p);
101  return *this;
102  }
103 
104  python_ptr & operator=(python_ptr const & r)
105  {
106  reset(r.ptr_);
107  return *this;
108  }
109 
110  ~python_ptr()
111  {
112  reset();
113  }
114 
115  void reset(pointer p = 0, refcount_policy rp = increment_count)
116  {
117  if(p == ptr_)
118  return;
119  if(rp == increment_count)
120  {
121  Py_XINCREF(p);
122  }
123  Py_XDECREF(ptr_);
124  ptr_ = p;
125  }
126 
127  pointer release(bool return_borrowed_reference = false)
128  {
129  pointer p = ptr_;
130  ptr_ = 0;
131  if(return_borrowed_reference)
132  {
133  Py_XDECREF(p);
134  }
135  return p;
136  }
137 
138  reference operator* () const
139  {
140  vigra_precondition(ptr_ != 0, "python_ptr::operator*(): Cannot dereference NULL pointer.");
141  return *ptr_;
142  }
143 
144  pointer operator-> () const
145  {
146  vigra_precondition(ptr_ != 0, "python_ptr::operator->(): Cannot dereference NULL pointer.");
147  return ptr_;
148  }
149 
150  pointer ptr() const
151  {
152  return ptr_;
153  }
154 
155  pointer get() const
156  {
157  return ptr_;
158  }
159 
160  operator pointer() const
161  {
162  return ptr_;
163  }
164 
165  bool operator! () const
166  {
167  return ptr_ == 0;
168  }
169 
170  bool unique() const
171  {
172  return ptr_ && ptr_->ob_refcnt == 1;
173  }
174 
175  void swap(python_ptr & other)
176  {
177  std::swap(ptr_, other.ptr_);
178  }
179 
180  bool operator==(python_ptr const & p) const
181  {
182  return ptr_ == p.ptr_;
183  }
184 
185  bool operator==(pointer p) const
186  {
187  return ptr_ == p;
188  }
189 
190  bool operator!=(python_ptr const & p) const
191  {
192  return ptr_ != p.ptr_;
193  }
194 
195  bool operator!=(pointer p) const
196  {
197  return ptr_ != p;
198  }
199 };
200 
201 inline void swap(python_ptr & a, python_ptr & b)
202 {
203  a.swap(b);
204 }
205 
206 inline python_ptr
207 getPythonDictionary(char const * k1 = 0, PyObject * a1 = 0,
208  char const * k2 = 0, PyObject * a2 = 0,
209  char const * k3 = 0, PyObject * a3 = 0)
210 {
211  python_ptr dict(PyDict_New(), python_ptr::keep_count);
212  pythonToCppException(dict);
213  if(k1 && a1)
214  PyDict_SetItemString(dict, k1, a1);
215  if(k2 && a2)
216  PyDict_SetItemString(dict, k2, a2);
217  if(k3 && a3)
218  PyDict_SetItemString(dict, k3, a3);
219  return dict;
220 }
221 
222 inline python_ptr pythonFromNumber(bool t)
223 {
224  python_ptr res(PyBool_FromLong(t ? 1 : 0), python_ptr::keep_count);
225  pythonToCppException(res);
226  return res;
227 }
228 
229 #define VIGRA_PYTHON_NUMBER_CONVERSION(type, condition, fct1, fct2) \
230 inline python_ptr pythonFromNumber(type t) \
231 { \
232  python_ptr res; \
233  if(condition) \
234  res = python_ptr(fct1(t), python_ptr::keep_count); \
235  else \
236  res = python_ptr(fct2(t), python_ptr::keep_count); \
237  pythonToCppException(res); \
238  return res; \
239 }
240 
241 VIGRA_PYTHON_NUMBER_CONVERSION(signed char, true, PyInt_FromLong, PyInt_FromLong)
242 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned char, true, PyInt_FromLong, PyInt_FromLong)
243 VIGRA_PYTHON_NUMBER_CONVERSION(short, true, PyInt_FromLong, PyInt_FromLong)
244 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned short, true, PyInt_FromLong, PyInt_FromLong)
245 VIGRA_PYTHON_NUMBER_CONVERSION(long, true, PyInt_FromLong, PyInt_FromLong)
246 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned long, sizeof(unsigned long) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyLong_FromUnsignedLongLong)
247 VIGRA_PYTHON_NUMBER_CONVERSION(int, sizeof(long) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyInt_FromLong)
248 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned int, sizeof(unsigned int) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyLong_FromUnsignedLongLong)
249 VIGRA_PYTHON_NUMBER_CONVERSION(long long, true, PyLong_FromLongLong, PyLong_FromLongLong)
250 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned long long, true, PyLong_FromUnsignedLongLong, PyLong_FromUnsignedLongLong)
251 VIGRA_PYTHON_NUMBER_CONVERSION(float, true, PyFloat_FromDouble, PyFloat_FromDouble)
252 VIGRA_PYTHON_NUMBER_CONVERSION(double, true, PyFloat_FromDouble, PyFloat_FromDouble)
253 
254 #undef VIGRA_PYTHON_NUMBER_CONVERSION
255 
256 template <class T, int N>
257 python_ptr shapeToPythonTuple(TinyVector<T, N> const & shape)
258 {
259  python_ptr tuple(PyTuple_New(N), python_ptr::keep_count);
260  pythonToCppException(tuple);
261  for(unsigned int k=0; k<N; ++k)
262  {
263  PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromNumber(shape[k]).release());
264  }
265  return tuple;
266 }
267 
268 template <class T>
269 python_ptr shapeToPythonTuple(ArrayVectorView<T> const & shape)
270 {
271  python_ptr tuple(PyTuple_New(shape.size()), python_ptr::keep_count);
272  pythonToCppException(tuple);
273  for(unsigned int k=0; k<shape.size(); ++k)
274  {
275  PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromNumber(shape[k]).release());
276  }
277  return tuple;
278 }
279 
280 
281 } // namespace vigra
282 
283 #endif // VIGRA_PYTHON_UTILITY_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.1 (Wed Mar 12 2014)