[C++-sig] Boost iterators
David Abrahams
david.abrahams at rcn.com
Thu Apr 25 21:29:11 CEST 2002
----- Original Message -----
From: "Martin Casado" <casado2 at llnl.gov>
To: "David Abrahams" <david.abrahams at rcn.com>
Cc: "pysig" <c++-sig at python.org>
Sent: Wednesday, April 24, 2002 6:00 PM
Subject: Re: Re: [C++-sig] Boost iterators
> > Rather than adding cruft to each function which returns a
vector<int>,
> > What I think you want is a def_iterator() function on class_<>. Then
you
> > just write:
> >
> > .add(class_<std::vector<int> >("int_vector")
> > .def_iterator())
>
> Dave,
>
> I've had some more time to look into iterator support. I've written
a
> function template which accepts an stl container conforming type and
> returns a PyIterator thingy like so..
>
> template <typename T>
> PyIter<vector<int> > foo(T& t)
> {
> return PyIter<vector<int> >(t.begin(),t.end());
> }
>
> I then simply add this to my class with def(..)
>
> class_<vector<int> >("vector_int")
> .def_init()
> .def("__iter__",static_cast<PyIter<vector<int> >
> (*)(vector<int>&)>(foo)) >
I don't understand why you need the cast here; it seems as though
&foo<vector<int> > would do just as well.
> .def("push_back",&vector<int>::push_back)
>
> I've hacked class.hpp to add a .def_iterator() which does exactly
that
> in the background so now all I have to do is:
>
> class_<goo>("goo").def_iterator()
Cool!
> This all seems to work fine however I do have a couple of concerns
>
> 1. The return value maintins references to the container's
iterators.
> Is there a way to keep the container alive as long as the python
> iterator object is alive? Something like
return_internal_reference(),
> but handles values which maintain internal references.
How about with_custodian_and_ward<0,1>() should handle it, right? You
want the self argument (argument 1) to stay alive as long as the return
value.
>
> 2. For each PyIter< > instance used, I have to create a class within
> boost. Such as:
>
> class_<PyIter<vector<int> > >
>
> Would it be possible to do this on the fly, like during calls
> to .def_iterator()?
Well, the Python object for the iterator type could be attached to the
class being defined, instead of the module, if that's what you mean.
self& def_iterator()
{
class_<PyIter<T> > iter_class("iterator");
// now the iterator class is stored in an attribute of the
container class
Py_SetAttrString(this->object().get(), "iterator",
iter_class.object().get());
...
}
-Dave
More information about the Cplusplus-sig
mailing list