Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2000-11-21 10:11:09

----- Original Message -----
From: "Anton Gluck" <gluc_at_[hidden]>

> My work with py_cpp has been going very well lately, and it proved to be a
> very useful tool for me.


> I have now a a quite good Python interface to
> many of the classes in a dll which I am trying to expose. However, I am
> having a problem exposing an iterator that is a typedef for const_iterator
> of vector. This is meant to be an iterator through a vector of variables
> (Vars).
> My first problem is how to expose the iterator. This is how it is defined
> in VarList.h:
> typedef std::vector<Var*>::const_iterator VarListConstIter;

Yeah, but the underlying problem is surely that vector<>::const_iterator is
a raw pointer in your implementation.

> This is the code from VarList.cpp:
> VarList::VarListConstIter VarList::Begin() const {
> return fMe.begin();
> }
> In my wrapper code I tried to expose VarList.Begin() like this:
> VarList_class.def(VarList::Begin, "Begin");


> I tried to write my own to_python function by including this (the idea
> was to write a to_python for the return of a pointer to a Var):
> template class py::ExtensionClass<Var>;
> PyObject* to_python(const Var* v)
> {
> return to_python(*v);
> }
> But the error messages stayede the same.
> I have also tried to expose VarListConstIter itself:
> py::ClassWrapper<VarList::VarListConstIter>
> VarListConstIter_class(ClusterForPy, "VarListConstIter");
> But this didn't go down well at all:
> d:\py_cpp/class_wrapper.h(47) : error C2143: syntax error : missing ','
> before '<tag>::*'


Yeah, wrapped types are really expected to be class types, and your
const_iterator is undoubtedly a pointer. I'm a little surprised, as you'd
think the uses of member pointers (like what it's complaining about)
wouldn't be instantiated unless used, but you never can tell with MSVC ;-).
Anyway, I shouldn't be too surprised, as I didn't design it to work that

> I think the problem here is with the return of pointers, which I tried to
> solve by adding my own to_python. But I've probably not written it
> correctly. Does this require one of the three "dangerous" to_python
> approaches described in your documentation?

Not neccessarily. The easiest way to avoid danger is:

Don't expose iterators. Python has its own iteration idioms (e.g. "for x in
S"), so just support the python sequence interface on your vector. Since
your vector is a random-access container, this will be fast. I reccommend
this approach.

There is another way which is less dangerous than those mentioned in the
documentation but more dangerous than the one mentioned above. It's
complicated to explain, though; I suggest you stick with the one above.

> The second question I have here is more conceptual: In C++ const_iterator
> can be used in a for loop, going from address a to address z. In my case
> it would be something like this:
> for (VarList::VarListConstIter iter = varlist.Begin(); iter !=
> varlist.End(); iter++) {
> Var v = *iter;
> // do something with each variable
> }
> Is it possible to do this with the exposed iterator in Python? If not, how
> can I loop through the list of Vars, which is of unknown length? Do I need
> to add a new function to VarList that will allow me to create a normal for
> loop in Python (one that goes from 0 to the length of the list)? Should I
> write a function that allows me access to the vector of Vars directly, so
> that I could determine its length for example?

I think that would be fine. You /can/ iterate over a sequence of unknown
length in python, though I don't think you need that in your case. In any
case, to support the sequence interface, model your vector interface after
the dangerous_array example, i.e. expose __getitem__, __setitem__ (if you
want it to be writable) and expecially remember to throw the
PyExc_IndexError when the index is out-of-range. This will allow you to
write "for x in S".

Good luck,

Boost list run by bdawes at, gregod at, cpdaniel at, john at