[C++-sig] Problem with map_indexing_suite

Damien Dupuis damien.dupuis at lip6.fr
Mon Jul 12 15:04:24 CEST 2010


Since I didn't find any solution when using map_indexing_suite, I wrote a simple wrapping that works in my case :

==============
#include <map>
#include <boost/python.hpp>

namespace myProject {
template<class Key, class Val>
struct map_item {
    typedef std::map<Key,Val> Map;

    static Val get(Map & self, const Key idx) {
      if (self.find(idx) == self.end()) {
          PyErr_SetString(PyExc_KeyError,"Map key not found");
          throw_error_already_set();
      }
      return self[idx];
    }

    static void set(Map& self, const Key idx, const Val val) { self[idx]=val; }
    static void del(Map& self, const Key n)                  { self.erase(n); }
    static bool in (Map const& self, const Key n)            { return self.find(n) != self.end(); }

    static list keys(Map const& self) {
        list t;
        for(typename Map::const_iterator it = self.begin() ; it!=self.end() ; ++it)
            t.append(it->first);
        return t;
    }

    static list values(Map const& self) {
        list t;
        for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it)
            t.append(it->second);
        return t;
    }

    static list items(Map const& self) {
        list t;
        for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it)
            t.append( make_tuple(it->first, it->second) );
        return t;
    }
};

#define STL_MAP_WRAPPING_PTR(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME)               \
    class_<std::pair<const KEY_TYPE, VALUE_TYPE> >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \
        .def_readonly ("key"  , &std::pair<const KEY_TYPE, VALUE_TYPE>::first ) \
        .def_readwrite("value", &std::pair<const KEY_TYPE, VALUE_TYPE>::second) \
    ;                                                                          \
    class_<std::map<KEY_TYPE, VALUE_TYPE> >(PYTHON_TYPE_NAME)                  \
        .def("__len__"     , &std::map<KEY_TYPE, VALUE_TYPE>::size)            \
        .def("__iter__"    , boost::python::iterator<std::map<KEY_TYPE, VALUE_TYPE>, return_internal_reference<> >()) \
        .def("__getitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().get, return_internal_reference<>()) \
        .def("__setitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().set   )         \
        .def("__delitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().del   )         \
        .def("__contains__", &map_item<KEY_TYPE, VALUE_TYPE>().in    )         \
        .def("clear"       , &std::map<KEY_TYPE, VALUE_TYPE>::clear  )         \
        .def("has_key"     , &map_item<KEY_TYPE, VALUE_TYPE>().in    )         \
        .def("keys"        , &map_item<KEY_TYPE, VALUE_TYPE>().keys  )         \
        .def("values"      , &map_item<KEY_TYPE, VALUE_TYPE>().values)         \
        .def("items"       , &map_item<KEY_TYPE, VALUE_TYPE>().items )         \
    ;

#define STL_MAP_WRAPPING(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME)               \
    class_<std::pair<const KEY_TYPE, VALUE_TYPE> >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \
        .def_readonly ("key"  , &std::pair<const KEY_TYPE, VALUE_TYPE>::first ) \
        .def_readwrite("value", &std::pair<const KEY_TYPE, VALUE_TYPE>::second) \
    ;                                                                          \
    class_<std::map<KEY_TYPE, VALUE_TYPE> >(PYTHON_TYPE_NAME)                  \
        .def("__len__"     , &std::map<KEY_TYPE, VALUE_TYPE>::size)            \
        .def("__iter__"    , boost::python::iterator<std::map<KEY_TYPE, VALUE_TYPE>, return_internal_reference<> >()) \
        .def("__getitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().get   )         \
        .def("__setitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().set   )         \
        .def("__delitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().del   )         \
        .def("__contains__", &map_item<KEY_TYPE, VALUE_TYPE>().in    )         \
        .def("clear"       , &std::map<KEY_TYPE, VALUE_TYPE>::clear  )         \
        .def("has_key"     , &map_item<KEY_TYPE, VALUE_TYPE>().in    )         \
        .def("keys"        , &map_item<KEY_TYPE, VALUE_TYPE>().keys  )         \
        .def("values"      , &map_item<KEY_TYPE, VALUE_TYPE>().values)         \
        .def("items"       , &map_item<KEY_TYPE, VALUE_TYPE>().items )         \
    ;

} // namespace
=================



Simply use STL_MAP_WRAPPING_PTR(KeyClass, ClassA*, "ClassAMap") to bind a map<KeyClass, ClassA*>
or STL_MAP_WRAPPING(KeyClass, ClassB, "ClassBMap") to bind a map<KeyClass, ClassB>

This code works in my case, fell free to correct or complete any error / missing.

-------------------------------
Damien Dupuis

Le 12 juil. 2010 à 09:13, Pentix a écrit :

> 
> Hi, Damien!
> 
> I've got exactly the same problem... Have you got any achievements?
> 
> 
> 
> Damien Dupuis wrote:
>> 
>> error: no match for call to ‘(const
>> boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<X*>)
>> (X*)‘
>> 
> 
> -- 
> View this message in context: http://old.nabble.com/Problem-with-map_indexing_suite-tp28925347p29135982.html
> Sent from the Python - c++-sig mailing list archive at Nabble.com.
> 
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
> 








-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20100712/6a5994a7/attachment.html>


More information about the Cplusplus-sig mailing list