[C++-sig] Re: iter(std::map<K*,V>)
David Abrahams
dave at boost-consulting.com
Wed Jun 18 15:03:47 CEST 2003
"Mike Rovner" <mike at bindkey.com> writes:
> Hi all,
>
> I want to wrap a std::map container, which maps some pointer to wrapped
> class to another wrapped class.
> typedef std::map<const Key*,Value> Map;
>
> In order to support 'for x in Map():' construct I need to implement
> __iter__.
> As I did for keys() call, I'd like to return ptr(it->first) as an iteration
> result.
OK...
> What is more simple (or recommended) way to do it?
>
> - Write and wrap helper iterator object with __iter__ and next methods like
> struct Map_iter
> {
> Map_iter(const Map& m) : it(m.begin()), itend(m.end()) {}
> Map_iter& identity(Map_iter& self) {return self;}
> object next() {
> if( it!=itend ) return ptr(it->first);
> PyErr_SetString(PyExc_StopIteration,"");
> throw_error_already_set();
> }
> private:
> Map::const_iterator it, itend;
> };
> Map_iter get_iterator(const Map& m) { return Map_iter(m); }
> and then
> class_<Map_iter>("_iter")
> .def("__iter__", &Map_iter::identity)
> .def("next", &Map_iter::next)
> ;
> //... and in Map wrapper
> .def("__iter__", get_iterator)
>
> or
> - Use iterator<>() with special return policy like
> .def("__iter__", iterator<Map, return_value_policy<copy_map_key_ptr> >())
I guess whichever one is shorter. The 2nd one looks pretty good.
> If later, I can't figure out the body of apply for my special return policy:
>
> struct copy_map_key_ptr
> {
> template <class T>
> struct apply
> {
> typedef to_python_value< ??? > type;
> };
> };
>
> Any suggestions?
Well, to_python_value is the wrong thing there, unless you want the
stds::pair<Key*,Value> referenced by the iterator to be copied into a
new Python object. I don't think you've wrapped
std::pair<Key*,Value> have you?
http://www.boost.org/libs/python/doc/v2/ResultConverter.html
describes the requirements for apply<T>::type. Its convertible()
function should return true and its function-call operator should
produce a PyObject* (owned reference). Something like
PyObject* operator()(std::pair<KeyType*,Value> const& x) const
{
return python::incref(
python::object(ptr(x.first)).ptr()
);
}
ought to work.
HTH,
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list