[python] non-standard iteration / wrapping member function return value

Hi, I'm stuck at trying to make python bindings for a set of classes that use a non-c++-standard iteration protocol. I've made a minimal example of what I'm trying to do: the python-ized classes look in essence like this: //------------------------------------------------------------- class int_range { private: int i, max; public: int_range(int m) : i(0), max(m) { } bool empty(void) const { return i > max; } int front(void) const { return i; } void next(void) { ++i; } }; class range_maker { public: int_range make(void) const { return int_range(10); } }; //------------------------------------------------------------- the boost.python module that I've come up with so far: //------------------------------------------------------------- using namespace boost::python; class _py_int_range_iter { private: int_range _range; public: _py_int_range_iter(int_range range) : _range(range) { } _py_int_range_iter self(void) { return *this; } int next(void) { if(_range.empty()) objects::stop_iteration_error(); int result = _range.front(); _range.next(); return result; } }; class_<_py_int_range_iter>("_py_int_range_iter", init<const int_range&>()) .def("self", &_py_int_range_iter::self) .def("next", &_py_int_range_iter::next) ; class _py_int_range { private: int_range _range; public: _py_int_range(int_range range) : _range(range) { } _py_int_range_iter iter(void) { return _py_int_range_iter(_range); } }; class_<_py_int_range>("_py_int_range", init<const int_range&>()) .def("__iter__", &_py_int_range::iter) ; //------------------------------------------------------------- the problem is that when I register range_maker as follows... //------------------------------------------------------------- class_<range_maker>("range_maker") .def("make", &range_maker::make) ; //------------------------------------------------------------- ... it compiles but (obviously) fails in python at run-time because range_maker::make returns int_range and not _py_int_range. what do I need to do to make this work? I know that I could write _py_range_maker wrapping range_maker and let it return _py_int_range, but this approach does not scale very well. Is there some way to tell the def(...) function that I want to wrap the return value into an object of another type? Is there a return value policy for that or do I need to write my own? If so how? Thanks in advance Matus

AMDG On 06/04/2013 10:07 AM, Matus Chochlik wrote:
Hi,
I'm stuck at trying to make python bindings for a set of classes that use a non-c++-standard iteration protocol. I've made a minimal example of what I'm trying to do:
the python-ized classes look in essence like this:
//------------------------------------------------------------- class int_range;
<snip>
class _py_int_range;
class_<_py_int_range>("_py_int_range", init<const int_range&>()) .def("__iter__", &_py_int_range::iter) ; //-------------------------------------------------------------
the problem is that when I register range_maker as follows...
//------------------------------------------------------------- class_<range_maker>("range_maker") .def("make", &range_maker::make) ; //-------------------------------------------------------------
... it compiles but (obviously) fails in python at run-time because range_maker::make returns int_range and not _py_int_range.
<snip>
It would probably work better if you adapted int_range directly instead of creating a separate class for python. (Def can take a function pointer. You don't have to use a member function) In Christ, Steven Watanabe
participants (2)
-
Matus Chochlik
-
Steven Watanabe