[C++-sig] boost::python::object and stl::map warning
Cedric Shock
cedric at shockfamily.net
Wed Oct 15 23:33:44 CEST 2003
To whomever can provide some assistance:
The following simple code (included below) attempts to implement a
std::map of boost::python::object.
I have defined a map of the objects as:
std::map<boost::python::object, boost::python::object> data;
Given boost::python::objects oi and ov, the following works:
data[oi] = ov;
However, the follwing statements all produce a warning (explained below):
ov = data[oi];
data.count(oi);
data[oi].ptr();
So assignment to the map is warning free, however, attempting to read
from the map raises this warning.
It compiles with g++ 3.2.2, and will work as expected in python.
However, for each of those offending statements it produces a warning like:
(data.count(oi)):
warning: cannot pass objects of non-POD type `struct
std::_Rb_tree_iterator<std::pair<const boost::python::api::object,
boost::python::api::object>, const std::pair<const
boost::python::api::object, boost::python::api::object>&, const
std::pair<const boost::python::api::object,
boost::python::api::object>*>' through `...'; call will abort at runtime
(data[oi].ptr()):
warning: cannot pass objects of non-POD type `struct
std::_Rb_tree_iterator<std::pair<const boost::python::api::object,
boost::python::api::object>, std::pair<const boost::python::api::object,
boost::python::api::object>&, std::pair<const
boost::python::api::object, boost::python::api::object>*>' through
`...'; call will abort at runtime
This warning usually indicates that something bad has been done with a
variable argument function like passing a non-POD type to printf. But it
should not be an issue here. std::map is routinely used to deal with
non-POD objects, why can't it handle the boost::python::object?
Thank you in advance for your help,
Cedric A. Shock
#############################################################
#include <map>
#include <boost/python.hpp>
// Interface for map
class PyObjectMap {
public:
int contains(PyObject* index);
PyObject* getitem(PyObject* index);
void setitem(PyObject* index, PyObject* value);
private:
std::map<boost::python::object, boost::python::object> data;
};
// Implelementation of map:
int PyObjectMap::contains(PyObject* index) {
// Convert PyObject* to an object:
boost::python::object o(boost::python::borrowed(index));
// Return whether it is in the map:
return data.count(o);
}
PyObject* PyObjectMap::getitem(PyObject* index) {
// Convert PyObject* to an object:
boost::python::object o(boost::python::borrowed(index));
if (data.count(o)) {
// Get the pointer:
PyObject* ptr;
ptr = data[o].ptr();
// We are returning it.
// That means there's one more reference out there:
boost::python::incref(ptr);
//return ptr;
return ptr;
} else {
// Raise an exception: IndexError
// Not implemented yet
return 0;
}
}
void PyObjectMap::setitem(PyObject* index, PyObject* value) {
// Convert PyObject* to objects:
boost::python::object oi(boost::python::borrowed(index));
boost::python::object ov(boost::python::borrowed(value));
// Store the value
data[oi] = ov;
}
using namespace boost::python;
BOOST_PYTHON_MODULE(map)
{
class_<PyObjectMap>("map")
.def("getitem", &PyObjectMap::getitem)
.def("__getitem__", &PyObjectMap::getitem)
.def("setitem", &PyObjectMap::setitem)
.def("__setitem__", &PyObjectMap::setitem)
.def("contains", &PyObjectMap::contains)
.def("__contains__", &PyObjectMap::contains)
;
}
####################################################
More information about the Cplusplus-sig
mailing list