896
Comment:
|
1634
scitbx approach added
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
==== Iterators ==== | === С++ Iterators === |
Line 21: | Line 21: |
* The ability to specify [http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/CallPolicies.html CallPolicies], e.g. to prevent copying of heavyweight values: | * The ability to specify ["boost.python/CallPolicy"], e.g. to prevent copying of heavyweight values: |
Line 29: | Line 29: |
=== Сustom Iterators === Suppose we have custom iterator class providing next() member function. To expose it let's take an approach from scitbx package: {{{ inline object pass_through(object const& o) { return o; } template<class Klass, class KlassIter> struct iterator_wrappers { static Klass next(KlassIter& o) { Klass* result = o.next(); if (!result) { PyErr_SetString(PyExc_StopIteration, "No more data."); boost::python::throw_error_already_set(); } return *result; } static void wrap(const char* python_name) { //using namespace boost::python; class_<KlassIter>(python_name, no_init) .def("next", next) .def("__iter__", pass_through) ; } }; }}} ... (to be continued) |
С++ Iterators
Python iterator support a highly flexible interface allowing:
- Direct exposure of a class' begin() and end() functions:
... .def("__iter__", iterator<list_int>())
- Creation of iterators from member functions...
... .def("__iter__" , range(&my_class::x_begin, &my_class::x_end))
- ...and member data:
... .def("__iter__" , range(&std::pair<char*,char*>::first, &std::pair<char*,char*>::second))
- The ability to specify ["boost.python/CallPolicy"], e.g. to prevent copying of heavyweight values:
... .def("__iter__" , range<return_value_policy<copy_non_const_reference> >( &my_sequence<heavy>::begin , &my_sequence<heavy>::end))
Сustom Iterators
Suppose we have custom iterator class providing next() member function. To expose it let's take an approach from scitbx package:
inline object pass_through(object const& o) { return o; } template<class Klass, class KlassIter> struct iterator_wrappers { static Klass next(KlassIter& o) { Klass* result = o.next(); if (!result) { PyErr_SetString(PyExc_StopIteration, "No more data."); boost::python::throw_error_already_set(); } return *result; } static void wrap(const char* python_name) { //using namespace boost::python; class_<KlassIter>(python_name, no_init) .def("next", next) .def("__iter__", pass_through) ; } };
... (to be continued)