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

vigra/python_utility.hxx
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)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.7.0 (Thu Aug 25 2011)