// Example by Ralf W. Grosse-Kunstleve #include namespace python = boost::python; namespace { // Avoid cluttering the global namespace. // A wrapper is used to define additional constructors. // struct vector_double_wrapper: std::vector { // Tell the compiler how to convert a base class object to // this wrapper object. vector_double_wrapper(PyObject*, const std::vector& vd) : std::vector(vd) {} vector_double_wrapper(PyObject* self) : std::vector() {} vector_double_wrapper(PyObject* self, int n) : std::vector(n) {} vector_double_wrapper(PyObject* self, python::tuple tuple) : std::vector(tuple.size()) { std::vector::iterator vd = begin(); for (int i = 0; i < tuple.size(); i++) vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), python::type()); } }; void raise_vector_IndexError() { PyErr_SetString(PyExc_IndexError, "vector index out of range"); python::throw_error_already_set(); } double getitem(const std::vector& vd, std::size_t key) { if (key >= vd.size()) raise_vector_IndexError(); return vd[key]; } void setitem(std::vector& vd, std::size_t key, double d) { if (key >= vd.size()) raise_vector_IndexError(); std::vector::iterator vditer = vd.begin(); vditer[key] = d; } void delitem(std::vector& vd, std::size_t key) { if (key >= vd.size()) raise_vector_IndexError(); std::vector::iterator vditer = vd.begin(); vd.erase(vditer + key); } // Convert vector_double to a regular Python tuple. // python::tuple as_tuple(const std::vector& vd) { python::tuple t(vd.size()); for (int i = 0; i < vd.size(); i++) t.set_item(i, python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); return t; } // Function returning a vector_double object to Python. // std::vector foo(int n) { std::vector vd(n); std::vector::iterator vditer = vd.begin(); for (int i = 0; i < n; i++) vditer[i] = double(i); return vd; } // Same as foo(), but avoid copying on return. // std::auto_ptr > bar(int n) { std::auto_ptr > vdptr(new std::vector(n)); std::vector::iterator vditer = vdptr->begin(); for (int i = 0; i < n; i++) vditer[i] = double(10 * i); return vdptr; } } BOOST_PYTHON_MODULE_INIT(simple_vector) { python::module_builder this_module("simple_vector"); python::class_builder, vector_double_wrapper> vector_double(this_module, "vector_double"); vector_double.def(python::constructor()); vector_double.def(python::constructor<>()); vector_double.def(python::constructor()); vector_double.def(&std::vector::size, "__len__"); vector_double.def(getitem, "__getitem__"); vector_double.def(setitem, "__setitem__"); vector_double.def(delitem, "__delitem__"); vector_double.def(as_tuple, "as_tuple"); this_module.def(foo, "foo"); this_module.def(bar, "bar"); }