// Based on wrapVector.hh by Mike Owen and Jeff Johnson. // http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/spheral/src/src/BPLWraps/CXXWraps/ #ifndef BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H #define BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H #include namespace example { // A wrapper is used to define additional constructors. This wrapper // is templated on the template parameter for its corresponding vector. template struct vector_wrapper: std::vector { // Tell the compiler how to convert a base class object to // this wrapper object. vector_wrapper(PyObject*, const std::vector& vec): std::vector(vec) {} vector_wrapper(PyObject* self): std::vector() {} vector_wrapper(PyObject* self, std::size_t n): std::vector(n) {} vector_wrapper(PyObject* self, boost::python::tuple tuple): std::vector(tuple.size()) { std::vector::iterator vec = begin(); for (std::size_t i = 0; i < tuple.size(); i++) vec[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), boost::python::type()); } }; void raise_vector_IndexError() { PyErr_SetString(PyExc_IndexError, "vector index out of range"); boost::python::throw_error_already_set(); } template struct vector_access { static T getitem(const std::vector& vec, std::size_t key) { if (key >= vec.size()) raise_vector_IndexError(); return vec[key]; } static void setitem(std::vector& vec, std::size_t key, const T &value) { if (key >= vec.size()) raise_vector_IndexError(); vec[key] = value; } static void delitem(std::vector& vec, std::size_t key) { if (key >= vec.size()) raise_vector_IndexError(); vec.erase(vec.begin() + key); } // Convert vector to a regular Python tuple. static boost::python::tuple as_tuple(const std::vector& vec) { // Create a python type of size vec.size(). boost::python::tuple t(vec.size()); for (std::size_t i = 0; i < vec.size(); i++) { t.set_item(i, boost::python::ref(BOOST_PYTHON_CONVERSION::to_python(vec[i]))); } return t; } }; // This function will build a vector and add it to the given // module with the given name. template boost::python::class_builder, vector_wrapper > wrap_vector(boost::python::module_builder& module, const std::string& vector_name, const T&) { // Add the vector to the module. boost::python::class_builder, vector_wrapper > py_vector(module, vector_name.c_str()); // Define constructors and methods for the vector. py_vector.def(boost::python::constructor<>()); py_vector.def(boost::python::constructor()); py_vector.def(boost::python::constructor()); py_vector.def(&std::vector::size, "__len__"); py_vector.def(&vector_access::getitem, "__getitem__"); py_vector.def(&vector_access::setitem, "__setitem__"); py_vector.def(&vector_access::delitem, "__delitem__"); py_vector.def(&vector_access::as_tuple, "as_tuple"); return py_vector; } } #endif // BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H