PyOW_Array.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2003-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00035 #ifndef PYOW_ARRAY_HPP_
00036 #define PYOW_ARRAY_HPP_
00037 #include <OW_String.hpp>
00038 #include <OW_Array.hpp>
00039 // note this comes *after* the OpenWBEM headers, because it has a
00040 // #define ANY void
00041 // which really screws up OpenWBEM
00042 #include <boost/python.hpp>
00043 #ifdef ANY
00044 #undef ANY
00045 #endif
00046 
00047 namespace OW_NAMESPACE
00048 {
00049 
00050 namespace {
00051 template <typename T>
00052 T T_getslice_(const T& a, int i, int j)
00053 {
00054    int len = a.size();
00055    if (i < 0)
00056    {
00057       i = 0;
00058    }
00059    if (j < 0)
00060    {
00061       j = 0;
00062    }
00063    if (i > j)
00064       return T();
00065    T rval(a);
00066    if (j < len)
00067    {
00068       rval.remove(j, len);
00069    }
00070    if (i > 0)
00071    {
00072       rval.remove(0, i);
00073    }
00074    return rval;
00075 }
00076 template <typename T>
00077 typename T::value_type T_getitem_(const T& t, int i)
00078 {
00079    if (i < 0 || i >= t.size())
00080    {
00081       // raise IndexError
00082       PyErr_SetString(PyExc_IndexError,
00083             "index out of range");
00084       boost::python::throw_error_already_set();
00085    }
00086    return t[i];
00087 }
00088 template <typename T>
00089 void T_setitem_(T& t, int i, const typename T::value_type& x)
00090 {
00091    if (i < 0 || i >= t.size())
00092    {
00093       // raise IndexError
00094       PyErr_SetString(PyExc_IndexError,
00095             "index out of range");
00096       boost::python::throw_error_already_set();
00097    }
00098    t[i] = x;
00099 }
00100 template <typename T>
00101 void T_delitem_(T& t, int i)
00102 {
00103    if (i < 0 || i >= t.size())
00104    {
00105       // raise IndexError
00106       PyErr_SetString(PyExc_IndexError,
00107             "index out of range");
00108       boost::python::throw_error_already_set();
00109    }
00110    t.erase(t.begin() + i);
00111 }
00112 template <typename T>
00113 int T_count(const T& s, typename T::value_type const& c)
00114 {
00115    int rval = 0;
00116    for (typename T::const_iterator i = s.begin(); i != s.end(); ++i)
00117    {
00118       if (*i == c)
00119          ++rval;
00120    }
00121    return rval;
00122 }
00123 template <typename T>
00124 void T_append(T& s, typename T::value_type const& c)
00125 {
00126    s.push_back(c);
00127 }
00128 template <typename T>
00129 int T_index(const T& s, typename T::value_type const& c)
00130 {
00131    for (typename T::const_iterator i = s.begin(); i != s.end(); ++i)
00132    {
00133       if (*i == c)
00134          return std::distance(s.begin(), i);
00135    }
00136    // Raise ValueError
00137    PyErr_SetString(PyExc_ValueError,
00138          "index(x): x not in list");
00139    boost::python::throw_error_already_set();
00140 }
00141 template <typename T>
00142 void T_insert(T& s, int i, typename T::value_type const& x)
00143 {
00144    typename T::size_type length = s.size();
00145    if (i < 0)
00146    {
00147       i = 0;
00148    }
00149    if (i >= length)
00150    {
00151       s.insert(s.end(), x);
00152    }
00153    else
00154    {
00155       s.insert(s.begin() + i, x);
00156    }
00157 }
00158 template <typename T>
00159 typename T::value_type T_pop(T& s, int i = -1)
00160 {
00161    typename T::size_type length = s.size();
00162    while (true)
00163    {
00164       if (i < 0)
00165       {
00166          i += length;
00167       }
00168       else if (i >= length)
00169       {
00170          i -= length;
00171       }
00172       else
00173       {
00174          break;
00175       }
00176    }
00177    typename T::value_type rval = s[i];
00178    s.erase(s.begin() + i);
00179    return rval;
00180 }
00181 BOOST_PYTHON_FUNCTION_OVERLOADS(T_pop_overloads, T_pop, 1, 2)
00182 template <typename T>
00183 void T_remove(T& s, typename T::value_type const& x)
00184 {
00185    int i = T_index(s, x);
00186    s.erase(s.begin() + i);
00187 }
00188 template <typename T>
00189 void T_reverse(T& s)
00190 {
00191    std::reverse(s.begin(), s.end());
00192 }
00193 template <typename T>
00194 void T_sort(T& s)
00195 {
00196    std::sort(s.begin(), s.end());
00197 }
00198 template <typename T>
00199 T T_add_(T const& x, T const& y)
00200 {
00201    T rval(x);
00202    rval.insert(rval.end(), y.begin(), y.end());
00203    return rval;
00204 }
00205 template <typename T>
00206 T& T_iadd_(T& x, T const& y)
00207 {
00208    x.insert(x.end(), y.begin(), y.end());
00209    return x;
00210 }
00211 template <typename T>
00212 T T_mul_(T const& x, int y)
00213 {
00214    T rval;
00215    for (int i = 0; i < y; ++i)
00216    {
00217       rval.insert(rval.end(), x.begin(), x.end());
00218    }
00219    return rval;
00220 }
00221 template <typename T>
00222 T T_rmul_(int y, T const& x)
00223 {
00224    return T_mul_(x, y);
00225 }
00226 template <typename T>
00227 T& T_imul_(T & x, int y)
00228 {
00229    if (y < 1)
00230    {
00231       x.clear();
00232       return x;
00233    }
00234    typename T::size_type l = x.size();
00235    x.reserve(y * l);
00236    for (int i = 1; i < y; ++i)
00237    {
00238       typename T::iterator end = x.begin();
00239       std::advance(end, l);
00240       x.insert(x.end(), x.begin(), end);
00241    }
00242    return x;
00243 }
00244 template <typename T>
00245 bool T_contains_(T const& self, typename T::value_type const& item)
00246 {
00247    return std::find(self.begin(), self.end(), item) != self.end();
00248 }
00249 template <typename T>
00250 PyObject* T_repr(const T& t)
00251 {
00252    String rval("owclient.Array<T>(");
00253    for (typename T::const_iterator i = t.begin(); i != t.end(); ++i)
00254    {
00255       boost::python::object o(*i);
00256       boost::python::str tmpstr(o.attr("__repr__")());
00257       rval += String(boost::python::extract<const char*>(tmpstr));
00258       if (i + 1 != t.end())
00259          rval += ", ";
00260    }
00261    rval += ")";
00262    return ::Py_BuildValue("s#", rval.c_str(), rval.length());
00263 }
00264 template <typename T>
00265 PyObject* T_str(const T& t)
00266 {
00267    String rval;
00268    for (typename T::const_iterator i = t.begin(); i != t.end(); ++i)
00269    {
00270       boost::python::object o(*i);
00271       boost::python::str tmpstr(o.attr("__str__")());
00272       rval += String(boost::python::extract<const char*>(tmpstr));
00273       if (i + 1 != t.end())
00274          rval += ", ";
00275    }
00276    return ::Py_BuildValue("s#", rval.c_str(), rval.length());
00277 }
00278 template <typename T>
00279 void registerArrayImpl(const char* className)
00280 {
00281    using namespace boost::python;
00282    typedef typename Array<T>::iterator iter_t;
00283    typedef typename Array<T>::const_iterator const_iter_t;
00284    typedef typename Array<T>::reverse_iterator riter_t;
00285    typedef typename Array<T>::size_type size_type;
00286    typedef typename Array<T>::reference reference;
00287    class_<Array<T> >(className)
00288       .def(init<size_type, const T&>())
00289       .def(init<int, const T&>())
00290       .def(init<long, const T&>())
00291       .def(init<size_type>())
00292       // these call the template constructor.  Since we have to instantiate
00293       // each type we want to expose, let's not go overboard!
00294       .def(init<iter_t, iter_t>())
00295       .def(init<const_iter_t, const_iter_t>())
00296       .def("begin", (iter_t (Array<T>::*)())(&Array<T>::begin))
00297       .def("end", (iter_t (Array<T>::*)())(&Array<T>::end))
00298       .def("__iter__", iterator<Array<T> >())
00299       .def("rbegin", (riter_t (Array<T>::*)())(&Array<T>::rbegin))
00300       .def("rend", (riter_t (Array<T>::*)())(&Array<T>::rend))
00301       .def("size", &Array<T>::size)
00302       .def("max_size", &Array<T>::max_size)
00303       .def("capacity", &Array<T>::capacity)
00304       .def("empty", &Array<T>::empty)
00305       .def(self += T())
00306       .def("reserve", &Array<T>::reserve)
00307       // These won't compile with T=native type
00308       //.def("front", (reference (Array<T>::*)())&Array<T>::front, return_internal_reference<>())
00309       //.def("back", (reference (Array<T>::*)())&Array<T>::back, return_internal_reference<>())
00310       .def("push_back", &Array<T>::push_back)
00311       .def("append", &Array<T>::append)
00312       .def("swap", &Array<T>::swap)
00313       .def("insert", (iter_t (Array<T>::*)(iter_t, const T&))&Array<T>::insert)
00314       .def("insert", (void (Array<T>::*)(size_type, const T&))&Array<T>::insert)
00315       .def("insert", (void (Array<T>::*)(iter_t, iter_t, iter_t))&Array<T>::insert)
00316       .def("remove", (void (Array<T>::*)(size_type))(&Array<T>::remove))
00317       .def("remove", (void (Array<T>::*)(size_type, size_type))(&Array<T>::remove))
00318       .def("appendArray", &Array<T>::appendArray)
00319       .def("pop_back", &Array<T>::pop_back)
00320       .def("erase", (iter_t (Array<T>::*)(iter_t))(&Array<T>::erase))
00321       .def("erase", (iter_t (Array<T>::*)(iter_t, iter_t))(&Array<T>::erase))
00322       .def("resize", (void (Array<T>::*)(size_type))(&Array<T>::resize))
00323       .def("resize", (void (Array<T>::*)(size_type, const T&))(&Array<T>::resize))
00324       .def("clear", &Array<T>::clear)
00325 //        .def("readObject", &Array<T>::readObject)
00326 //        .def("writeObject", &Array<T>::writeObject)
00327       .def(self == self)
00328       .def(self < self)
00329       // python container functions
00330       .def("__len__", &Array<T>::size)
00331       .def("__getslice__", &T_getslice_<Array<T> >)
00332       .def("__getitem__", &T_getitem_<Array<T> >)
00333       .def("__setitem__", &T_setitem_<Array<T> >)
00334       .def("__delitem__", &T_delitem_<Array<T> >)
00335       .def("append", &T_append<Array<T> >)
00336       .def("count", &T_count<Array<T> >)
00337       .def("index", &T_index<Array<T> >)
00338       .def("insert", &T_insert<Array<T> >)
00339       .def("pop", &T_pop<Array<T> >, T_pop_overloads(args("i")))
00340       .def("remove", &T_remove<Array<T> >)
00341       .def("reverse", &T_reverse<Array<T> >)
00342       .def("sort", &T_sort<Array<T> >)
00343       .def("__add__", &T_add_<Array<T> >)
00344       .def("__radd__", &T_add_<Array<T> >)
00345       .def("__iadd__", &T_iadd_<Array<T> >, return_internal_reference<1>())
00346       .def("__mul__", &T_mul_<Array<T> >)
00347       .def("__rmul__", &T_rmul_<Array<T> >)
00348       .def("__imul__", &T_imul_<Array<T> >, return_internal_reference<1>())
00349       .def("__contains__", &T_contains_<Array<T> >)
00350       .def("__repr__", &T_repr<Array<T> >)
00351       .def("__str__", &T_str<Array<T> >)
00352    ;
00353 }
00354 }
00355 
00356 } // end namespace OW_NAMESPACE
00357 
00358 #endif // #ifndef PYOW_ARRAY_HPP_

Generated on Thu Feb 9 08:48:29 2006 for openwbem by  doxygen 1.4.6