[ 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.1 (3 Dec 2010)