[C++-sig] iter(std::map<K*,V>)

Mike Rovner mike at bindkey.com
Tue Jun 17 22:40:15 CEST 2003


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.

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> >())

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?

Mike







More information about the Cplusplus-sig mailing list