[C++-sig] Re: Re: custom iterator object
Mike Rovner
mike at bindkey.com
Fri Nov 8 19:53:07 CET 2002
"David Abrahams" <dave at boost-consulting.com> wrote in message
news:uy9853yrt.fsf at boost-consulting.com...
> "Mike Rovner" <mike at bindkey.com> writes:
>
> >> > I have the following class, implementing my iterator protocol:
> >> >
> >> > template<class T>
> >> > class Iter
> >> > {
> >> > T* First();
> >> > T* Next();
> >> > }
> >> > returning 0, when iteration is done.
> >> >
> >> Boost.Python provides several ways to wrap regular C++ iterators as
> >> Python iterators. Did you consider using those?
> >
> > Sure I did, but couldn't figure out how to do it ;)
> > IMHO it's NOT a regular iterator because operations '*' and '++' are
> > combined into 'Next'.
>
> No, of course it's not. However, you could consider making a C++
> iterator using, say, the Boost Iterator Adaptors library, and then
> wrapping that. Maybe that's too much work, though.
>
> >> > I'm trying to wrap it to Python iterator protocol:
> >> What's "not good" about it?
> >
> > I have problems with return value. In __iter__ I have to return
> > self, but there is no Python self yet in wrapping class. So
> > probably I have to duplicate part of the BPL iterator guts, but I
> > got lost :(
>
> I'm lost, too. You haven't shown enough of what you're trying to do
> for me to be able to help. Please try showing the code you hope to use
> to wrap this stuff, and add lots of comments to describe what's
> happening.
>
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>())
.def("__iter__", range(&PyIter::begin, &PyIter::end))
but I still don't know how to instantiate it.
More information about the Cplusplus-sig
mailing list