[C++-sig] Random access iterators, and sequence protocol.

Nicodemus nicodemus at globalite.com.br
Sat Jul 5 18:41:41 CEST 2003


Hi Prabhu,

Prabhu Ramachandran wrote:

>Hi,
>
>I have a container class that defines an operator [] (std::size_t) and
>also has a size function that returns the number of elements in the
>container.  It does not provide access to an internal iterator.  To
>get the '[]' wrapped with Pyste I need to rename the function as
>__getitem__ of course.  I also renamed size to __len__.  However, I
>would like to do this:
>
>for i in container:
>   i.something()
>
>To do this __getitem__ needs to generate an IndexError when the index
>is greater than or equal to size.  Do I _have_ to register an
>exception translator from something like std::range_error?  Is there
>an easier way to do this?  The docs don't reveal any easier solutions.
>It would be nice if this were also as easy as doing it via range, or
>iterator. :)
>  
>

Make a wrapper for your __getitem__, that throws IndexError when an 
invalid index is passed (untested):


Object my__getitem__(Container& c, int index)
{
    if (index < 0) { // allow negative indexes
        index = c.size() + index;
    }

    if (index >= c.size()) {
        PyErr_SetString(PyExc_IndexError, "index out of range");
        boost::python::throw_error_already_set();
    }

    return c[index];
}

If you want to be able to set items in your container in Python with the 
[] operator, you will have to define also a __setitem__. 8)

Then in your pyste file:

Include('mywrappers.hpp')
Container = Class(...)
add_method(Container, 'my__getitem__')
add_method(Container, 'my__setitem__')

HTH,
Nicodemus.





More information about the Cplusplus-sig mailing list