|
Boost : |
From: Ullrich Koethe (koethe_at_[hidden])
Date: 2000-11-29 16:09:18
Anton Gluck wrote:
>
> Ullrich,
>
> On Mon, 27 Nov 2000, Ullrich Koethe wrote:
>
> > Petr Kocmid wrote:
> > >
> > > > 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.
> > >
> > > I predict the problem Anton had will arise many times in the future. Perhaps
> > > we can
> > > add some generic conversion of STL containers to sequence/mapping protocol
> > > to py_cpp.
> > >
> >
> >
> > I've implemented and successfully tested the following "Cursor"-feature
> > to wrap STL iterators:
> >
> > in C++:
> >
> > typedef std::list<Foo> FooList;
> > boost::python::class_builder<FooList> foolist_class(my_module,
> > "FooList");
> > foolist_class.def(boost::python::constructor<>());
> > foolist_class.def((void (FooList::*)(Foo const
> > &))&FooList::push_back, "append");
> >
> > // define a cursor for FooLists
> > my_module.def_cursor_for(foolist_class);
> >
> > Then in Python:
> >
> > >>> fooList = FooList()
> > >>> fooList.append(Foo(1))
> > >>> fooList.append(Foo(2))
> > >>>
> > >>> for i in fooList.cusor(): # use cursor in a loop
> > ... i
> > ... print i.getData()
> > ...
> > <Foo object at 111070>
> > 1
> > <Foo object at 1110e8>
> > 2
> > >>>
> > >>> c = fooList.cursor()
> > >>> c[1].getData() # use cursor to read and write the data
> > 2
> > >>> c[1] = Foo(4)
> > >>> c[1].getData()
> > 4
> >
> > Would this suit your needs ?
>
> I'm not sure if this was meant for me or Petr. I can see useful parts
> here when creating an iterator, but can't see how it helps exposing an
> existing iterator. I guess the magic is happening in
> "my_module.def_cursor_for(foolist_class);"?
>
Sorry for being too vague. It was meant for you and Petr (and anyone
interested in wrapping iterators).
Yes, the magic is happening in
my_module.def_cursor_for(foolist_class);". This line creates an
auxiliary class "FooList_cursor" that wraps FooList's iterator. In
addition, it adds the factory function "cursor()" to extension class
"FooList" itself.
The auxiliary cursor class can be created for *any STL conforming
container* (code attached below). In particular, the following is
needed:
FooList::iterator
FooList::value_type
FooList::begin()
FooList::size()
std::iterator_traits<FooList::iterator>::iterator_category
The cursor implements random access functions (get_item() and
set_item()) for any iterator, but these will only be as efficient as the
underlying iterator allows. However, this is not a problem because 'for
i in fooList.cusor():' accesses the items in forward order anyway. Only
problem: I don't know how MSVC distinguishes iterator categories, so on
this compiler everything is treated as a forward iterator. Any hints?
Regards
Ulli
template <class Container>
struct cursor
{
typedef typename Container::iterator iterator;
typedef typename Container::value_type value_type;
typedef typename iterator_traits<iterator>::iterator_category
iterator_category;
cursor(Container & c)
: m_begin(c.begin()),
m_iter(c.begin()),
m_size(c.size()),
m_index(0)
{}
void advance(int index, std::forward_iterator_tag)
{
if(index < 0 || index >= m_size)
{
PyErr_SetObject(PyExc_KeyError,
BOOST_PYTHON_CONVERSION::to_python(index));
throw python::error_already_set();
}
int delta = index - m_index;
if(delta < 0)
{
m_iter = m_begin;
delta = index;
}
std::advance(m_iter, delta);
m_index = index;
}
void advance(int index, std::bidirectional_iterator_tag)
{
if(index < 0 || index >= m_size)
{
PyErr_SetObject(PyExc_KeyError,
BOOST_PYTHON_CONVERSION::to_python(index));
throw python::error_already_set();
}
int delta = index - m_index;
std::advance(m_iter, delta);
m_index = index;
}
value_type const & get_item(int index)
{
advance(index, iterator_category());
return *m_iter;
}
void set_item(int index, value_type const & v)
{
advance(index, iterator_category());
*m_iter = v;
}
int len() const
{ return m_size; }
iterator m_begin, m_iter;
int m_index, m_size;
};
-- ________________________________________________________________ | | | Ullrich Koethe Universität Hamburg / University of Hamburg | | FB Informatik / Dept. of Computer Science | | AB Kognitive Systeme / Cognitive Systems Group | | | | Phone: +49 (0)40 42883-2573 Vogt-Koelln-Str. 30 | | Fax: +49 (0)40 42883-2572 D - 22527 Hamburg | | Email: u.koethe_at_[hidden] Germany | | koethe_at_[hidden] | | WWW: http://kogs-www.informatik.uni-hamburg.de/~koethe/ | |________________________________________________________________|
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk