一定要
std::list吗?如果使用,
std::vector则可以使用
boost::python::vector_indexing_suite包装列表。有关详细信息,请参见此帖子。
如果必须使用
std::list,则需要创建一个
std::list使用python
list方法包装功能的帮助程序类。这可能相当复杂,但是可行。
std_item.hpp:
#include <list>#include <algorithm>#include <boost/python.hpp>template<class T>struct listwrap{ typedef typename T::value_type value_type; typedef typename T::iterator iter_type; static void add(T & x, value_type const& v) { x.push_back(v); } static bool in(T const& x, value_type const& v) { return std::find(x.begin(), x.end(), v) != x.end(); } static int index(T const& x, value_type const& v) { int i = 0; for(T::const_iterator it=x.begin(); it!=x.end(); ++it,++i) if( *it == v ) return i; PyErr_SetString(PyExc_ValueError, "Value not in the list"); throw boost::python::error_already_set(); } static void del(T& x, int i) { if( i<0 ) i += x.size(); iter_type it = x.begin(); for (int pos = 0; pos < i; ++pos) ++it; if( i >= 0 && i < (int)x.size() ) { x.erase(it); } else { PyErr_SetString(PyExc_IndexError, "Index out of range"); boost::python::throw_error_already_set(); } } static value_type& get(T& x, int i) { if( i < 0 ) i += x.size(); if( i >= 0 && i < (int)x.size() ) { iter_type it = x.begin(); for(int pos = 0; pos < i; ++pos) ++it; return *it; } else { PyErr_SetString(PyExc_IndexError, "Index out of range"); throw boost::python::error_already_set(); } } static void set(T& x, int i, value_type const& v) { if( i < 0 ) i += x.size(); if( i >= 0 && i < (int)x.size() ) { iter_type it = x.begin(); for(int pos = 0; pos < i; ++pos) ++it; *it = v; } else { PyErr_SetString(PyExc_IndexError, "Index out of range"); boost::python::throw_error_already_set(); } }};template<class T>void export_STLList(const char* typeName){ using namespace boost::python; class_<std::list<T> >(typeName) .def("__len__", &std::list<T>::size) .def("clear", &std::list<T>::clear) .def("append", &listwrap<T>::add, with_custodian_and_ward<1,2>()) // to let container keep value .def("__getitem__", &listwrap<T>::get, return_value_policy<copy_non_const_reference>()) .def("__setitem__", &listwrap<T>::set, with_custodian_and_ward<1,2>()) // to let container keep value .def("__delitem__", &listwrap<T>::del) .def("__contains__", &listwrap<T>::in) .def("__iter__", iterator<std::list<T> >()) .def("index", &listwrap<T>::index);}
用法:
typedef std::list<int> intlist;export_STLList<int>("intlist");
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)