[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 2009 by Ullrich Koethe and Hans Meine */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 #ifndef VIGRA_PYTHON_UTILITY_HXX 00037 #define VIGRA_PYTHON_UTILITY_HXX 00038 00039 #include <Python.h> 00040 #include <algorithm> 00041 #include "vigra/error.hxx" 00042 #include "vigra/tinyvector.hxx" 00043 00044 00045 namespace vigra { 00046 00047 template <class PYOBJECT_PTR> 00048 void pythonToCppException(PYOBJECT_PTR obj) 00049 { 00050 if(obj != 0) 00051 return; 00052 PyObject * type, * value, * trace; 00053 PyErr_Fetch(&type, &value, &trace); 00054 if(type == 0) 00055 return; 00056 std::string message(((PyTypeObject *)type)->tp_name); 00057 if(PyString_Check(value)) 00058 { 00059 message += std::string(": ") + PyString_AS_STRING(value); 00060 } 00061 00062 Py_XDECREF(type); 00063 Py_XDECREF(value); 00064 Py_XDECREF(trace); 00065 throw std::runtime_error(message.c_str()); 00066 } 00067 00068 class python_ptr 00069 { 00070 private: 00071 PyObject * ptr_; 00072 00073 public: 00074 00075 typedef PyObject element_type; 00076 typedef PyObject value_type; 00077 typedef PyObject * pointer; 00078 typedef PyObject & reference; 00079 00080 enum refcount_policy { increment_count, borrowed_reference = increment_count, 00081 keep_count, new_reference = keep_count }; 00082 00083 explicit python_ptr(pointer p = 0, refcount_policy rp = increment_count) 00084 : ptr_( p ) 00085 { 00086 if(rp == increment_count) 00087 { 00088 Py_XINCREF(ptr_); 00089 } 00090 } 00091 00092 python_ptr(python_ptr const & p) 00093 : ptr_(p.ptr_) 00094 { 00095 Py_XINCREF(ptr_); 00096 } 00097 00098 python_ptr & operator=(pointer p) 00099 { 00100 reset(p); 00101 return *this; 00102 } 00103 00104 python_ptr & operator=(python_ptr const & r) 00105 { 00106 reset(r.ptr_); 00107 return *this; 00108 } 00109 00110 ~python_ptr() 00111 { 00112 reset(); 00113 } 00114 00115 void reset(pointer p = 0, refcount_policy rp = increment_count) 00116 { 00117 if(p == ptr_) 00118 return; 00119 if(rp == increment_count) 00120 { 00121 Py_XINCREF(p); 00122 } 00123 Py_XDECREF(ptr_); 00124 ptr_ = p; 00125 } 00126 00127 pointer release(bool return_borrowed_reference = false) 00128 { 00129 pointer p = ptr_; 00130 ptr_ = 0; 00131 if(return_borrowed_reference) 00132 { 00133 Py_XDECREF(p); 00134 } 00135 return p; 00136 } 00137 00138 reference operator* () const 00139 { 00140 vigra_precondition(ptr_ != 0, "python_ptr::operator*(): Cannot dereference NULL pointer."); 00141 return *ptr_; 00142 } 00143 00144 pointer operator-> () const 00145 { 00146 vigra_precondition(ptr_ != 0, "python_ptr::operator->(): Cannot dereference NULL pointer."); 00147 return ptr_; 00148 } 00149 00150 pointer ptr() const 00151 { 00152 return ptr_; 00153 } 00154 00155 pointer get() const 00156 { 00157 return ptr_; 00158 } 00159 00160 operator pointer() const 00161 { 00162 return ptr_; 00163 } 00164 00165 bool operator! () const 00166 { 00167 return ptr_ == 0; 00168 } 00169 00170 bool unique() const 00171 { 00172 return ptr_ && ptr_->ob_refcnt == 1; 00173 } 00174 00175 void swap(python_ptr & other) 00176 { 00177 std::swap(ptr_, other.ptr_); 00178 } 00179 00180 bool operator==(python_ptr const & p) const 00181 { 00182 return ptr_ == p.ptr_; 00183 } 00184 00185 bool operator==(pointer p) const 00186 { 00187 return ptr_ == p; 00188 } 00189 00190 bool operator!=(python_ptr const & p) const 00191 { 00192 return ptr_ != p.ptr_; 00193 } 00194 00195 bool operator!=(pointer p) const 00196 { 00197 return ptr_ != p; 00198 } 00199 }; 00200 00201 inline void swap(python_ptr & a, python_ptr & b) 00202 { 00203 a.swap(b); 00204 } 00205 00206 inline python_ptr 00207 getPythonDictionary(char const * k1 = 0, PyObject * a1 = 0, 00208 char const * k2 = 0, PyObject * a2 = 0, 00209 char const * k3 = 0, PyObject * a3 = 0) 00210 { 00211 python_ptr dict(PyDict_New(), python_ptr::keep_count); 00212 pythonToCppException(dict); 00213 if(k1 && a1) 00214 PyDict_SetItemString(dict, k1, a1); 00215 if(k2 && a2) 00216 PyDict_SetItemString(dict, k2, a2); 00217 if(k3 && a3) 00218 PyDict_SetItemString(dict, k3, a3); 00219 return dict; 00220 } 00221 00222 inline python_ptr pythonFromNumber(bool t) 00223 { 00224 python_ptr res(PyBool_FromLong(t ? 1 : 0), python_ptr::keep_count); 00225 pythonToCppException(res); 00226 return res; 00227 } 00228 00229 #define VIGRA_PYTHON_NUMBER_CONVERSION(type, condition, fct1, fct2) \ 00230 inline python_ptr pythonFromNumber(type t) \ 00231 { \ 00232 python_ptr res; \ 00233 if(condition) \ 00234 res = python_ptr(fct1(t), python_ptr::keep_count); \ 00235 else \ 00236 res = python_ptr(fct2(t), python_ptr::keep_count); \ 00237 pythonToCppException(res); \ 00238 return res; \ 00239 } 00240 00241 VIGRA_PYTHON_NUMBER_CONVERSION(signed char, true, PyInt_FromLong, PyInt_FromLong) 00242 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned char, true, PyInt_FromLong, PyInt_FromLong) 00243 VIGRA_PYTHON_NUMBER_CONVERSION(short, true, PyInt_FromLong, PyInt_FromLong) 00244 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned short, true, PyInt_FromLong, PyInt_FromLong) 00245 VIGRA_PYTHON_NUMBER_CONVERSION(long, true, PyInt_FromLong, PyInt_FromLong) 00246 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned long, sizeof(unsigned long) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyLong_FromUnsignedLongLong) 00247 VIGRA_PYTHON_NUMBER_CONVERSION(int, sizeof(long) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyInt_FromLong) 00248 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned int, sizeof(unsigned int) < sizeof(Py_ssize_t), PyInt_FromSsize_t, PyLong_FromUnsignedLongLong) 00249 VIGRA_PYTHON_NUMBER_CONVERSION(long long, true, PyLong_FromLongLong, PyLong_FromLongLong) 00250 VIGRA_PYTHON_NUMBER_CONVERSION(unsigned long long, true, PyLong_FromUnsignedLongLong, PyLong_FromUnsignedLongLong) 00251 VIGRA_PYTHON_NUMBER_CONVERSION(float, true, PyFloat_FromDouble, PyFloat_FromDouble) 00252 VIGRA_PYTHON_NUMBER_CONVERSION(double, true, PyFloat_FromDouble, PyFloat_FromDouble) 00253 00254 #undef VIGRA_PYTHON_NUMBER_CONVERSION 00255 00256 template <class T, int N> 00257 python_ptr shapeToPythonTuple(TinyVector<T, N> const & shape) 00258 { 00259 python_ptr tuple(PyTuple_New(N), python_ptr::keep_count); 00260 pythonToCppException(tuple); 00261 for(unsigned int k=0; k<N; ++k) 00262 { 00263 PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromNumber(shape[k]).release()); 00264 } 00265 return tuple; 00266 } 00267 00268 template <class T> 00269 python_ptr shapeToPythonTuple(ArrayVectorView<T> const & shape) 00270 { 00271 python_ptr tuple(PyTuple_New(shape.size()), python_ptr::keep_count); 00272 pythonToCppException(tuple); 00273 for(unsigned int k=0; k<shape.size(); ++k) 00274 { 00275 PyTuple_SET_ITEM((PyTupleObject *)tuple.get(), k, pythonFromNumber(shape[k]).release()); 00276 } 00277 return tuple; 00278 } 00279 00280 00281 } // namespace vigra 00282 00283 #endif // VIGRA_PYTHON_UTILITY_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|