[C++-sig] Re: Re: custom iterator object
David Abrahams
dave at boost-consulting.com
Sun Nov 10 05:30:34 CET 2002
"Mike Rovner" <mike at bindkey.com> writes:
> "David Abrahams" <dave at boost-consulting.com> wrote in message
> news:uy9853yrt.fsf at boost-consulting.com...
>> "Mike Rovner" <mike at bindkey.com> writes:
> So I have custom iterator 'Iter' as shown above. It's like Python iterator,
> so I tend to use it instead of wrapping in iterator.
> Now I have a class:
>
> class Scheme {
> Iter A();
> Iter B();
> Iter C();
> }
>
> which I want to exposure. So I write:
>
> BOOST_PYTHON_MODULE(Py1)
> {
> class_<Scheme>("Scheme")
> .def("__iter__", ???(&Scheme::A))
> .add_property("b", ???(&Scheme::B))
> .add_property("c", ??(&Scheme::C))
> ;
> }
>
> to pretend objects itself acts as iterator A, b and c as B and C. But I have
> trouble in places ???.
> I need a Python iterator object there like 'iterator' or 'range' functions
> return, but first I need to instantiate Iter with A|B|C member parameter to
> create a custom iterator.
>
> I can wrap an Iter as
>
> typedef Iter (*GetIterFunc)();
> template<class T>
> struct PyIter
> {
> PyIter(GetLrIterFunc const get_func) : started(false), it(get_func()) {}
> const T* begin() {return it.First();}
> const T* end() {return 0;}
> const T* operator++() {return v=it.Next();}
> const T operator*() {return *v;}
> private:
> bool started;
> T* v;
> Iter it;
> };
>
> class_<PyIter>("PyIter", init<GetIterFunc>())
OK, there's no point in bothering with the init<...> declaration
there. You might as well use no_init, since you're not going to
construct these from Python and Boost.Python doesn't have a way to
convert any Python objects to C++ function pointers.
> .def("__iter__", range(&PyIter::begin, &PyIter::end))
Well, you can't use range(...) here; that's intended for real C++
iterators, and you don't have any (PyIter doesn't conform).
Here's my suggestion:
Try doing what you need to do in Pure Python. Build a little
new-style class (derived from object) called Scheme, and add the
iterator interface you want to see. To do that, you may find
yourself building some little Python iterator classes.
Now, when you have all that working, translate your Python iterator
classes into C++, and wrap them with Boost.Python. Remember that the
iterator's own __iter__ method can be implemented by wrapping this
C++ function:
object identity(object x) { return x; }
HTH,
--
David Abrahams
dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution
More information about the Cplusplus-sig
mailing list