diff --git a/example/dvect.cpp b/example/dvect.cpp new file mode 100644 index 00000000..3228010c --- /dev/null +++ b/example/dvect.cpp @@ -0,0 +1,69 @@ +#include "ivect.h" +#include "dvect.h" +#include +#include +namespace python = boost::python; + +namespace { + + vects::ivect dvect_as_ivect(const vects::dvect& dv) + { + vects::ivect iv(dv.size()); + vects::ivect::iterator iviter = iv.begin(); + for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); + return iv; + } + + boost::python::tuple ivect_as_tuple(const vects::ivect& iv) + { + return iv.as_tuple(); + } + + std::auto_ptr auto_ptr_ivect(const vects::dvect& dv) + { + return std::auto_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::shared_ptr shared_ptr_ivect(const vects::dvect& dv) + { + return boost::shared_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::python::tuple auto_ptr_ivect_as_tuple(std::auto_ptr& iv) + { + return iv->as_tuple(); + } + + boost::python::tuple shared_ptr_ivect_as_tuple(boost::shared_ptr& iv) + { + return iv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initdvect() +{ + try + { + python::module_builder this_module("dvect"); + + python::x_class_builder dvect_class(this_module, "dvect"); + + python::import_class_builder ivect_class("ivect", "ivect"); + + dvect_class.def(python::constructor()); + dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); + dvect_class.def(dvect_as_ivect, "as_ivect"); + + this_module.def(ivect_as_tuple, "ivect_as_tuple"); + dvect_class.def(auto_ptr_ivect, "auto_ptr_ivect"); + dvect_class.def(shared_ptr_ivect, "shared_ptr_ivect"); + this_module.def(auto_ptr_ivect_as_tuple, "auto_ptr_ivect_as_tuple"); + this_module.def(shared_ptr_ivect_as_tuple, "shared_ptr_ivect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/dvect.h b/example/dvect.h new file mode 100644 index 00000000..8ffe7b50 --- /dev/null +++ b/example/dvect.h @@ -0,0 +1,32 @@ +#ifndef DVECT_H +#define DVECT_H + +#include +#include + +namespace vects { + + struct dvect : public std::vector + { + dvect() : std::vector() {} + dvect(size_t n) : std::vector(n) {} + dvect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // DVECT_H diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp index bbe4725a..4b64e4b8 100644 --- a/example/getting_started5.cpp +++ b/example/getting_started5.cpp @@ -70,7 +70,8 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // MillerIndex from_python(PyObject* p, python::type) { - python::tuple tup = python::tuple(python::ref(p, ref::increment_count)); + python::tuple tup + = python::tuple(python::ref(p, python::ref::increment_count)); if (tup.size() != 3) { PyErr_SetString(PyExc_ValueError, "expecting exactly 3 values in tuple."); diff --git a/example/ivect.cpp b/example/ivect.cpp new file mode 100644 index 00000000..f8ca8707 --- /dev/null +++ b/example/ivect.cpp @@ -0,0 +1,69 @@ +#include "ivect.h" +#include "dvect.h" +#include +#include +namespace python = boost::python; + +namespace { + + vects::dvect ivect_as_dvect(const vects::ivect& iv) + { + vects::dvect dv(iv.size()); + vects::dvect::iterator dviter = dv.begin(); + for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); + return dv; + } + + boost::python::tuple dvect_as_tuple(const vects::dvect& dv) + { + return dv.as_tuple(); + } + + std::auto_ptr auto_ptr_dvect(const vects::ivect& iv) + { + return std::auto_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::shared_ptr shared_ptr_dvect(const vects::ivect& iv) + { + return boost::shared_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::python::tuple auto_ptr_dvect_as_tuple(std::auto_ptr& dv) + { + return dv->as_tuple(); + } + + boost::python::tuple shared_ptr_dvect_as_tuple(boost::shared_ptr& dv) + { + return dv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initivect() +{ + try + { + python::module_builder this_module("ivect"); + + python::x_class_builder ivect_class(this_module, "ivect"); + + python::import_class_builder dvect_class("dvect", "dvect"); + + ivect_class.def(python::constructor()); + ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); + ivect_class.def(ivect_as_dvect, "as_dvect"); + + this_module.def(dvect_as_tuple, "dvect_as_tuple"); + ivect_class.def(auto_ptr_dvect, "auto_ptr_dvect"); + ivect_class.def(shared_ptr_dvect, "shared_ptr_dvect"); + this_module.def(auto_ptr_dvect_as_tuple, "auto_ptr_dvect_as_tuple"); + this_module.def(shared_ptr_dvect_as_tuple, "shared_ptr_dvect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/ivect.h b/example/ivect.h new file mode 100644 index 00000000..a0187307 --- /dev/null +++ b/example/ivect.h @@ -0,0 +1,32 @@ +#ifndef IVECT_H +#define IVECT_H + +#include +#include + +namespace vects { + + struct ivect : public std::vector + { + ivect() : std::vector() {} + ivect(size_t n) : std::vector(n) {} + ivect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // IVECT_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp new file mode 100644 index 00000000..82c3f049 --- /dev/null +++ b/example/noncopyable_export.cpp @@ -0,0 +1,24 @@ +#include +#include +namespace python = boost::python; + +#include "store.h" + +extern "C" +DL_EXPORT(void) +initnoncopyable_export() +{ + try + { + python::module_builder this_module("noncopyable_export"); + + python::xptr_class_builder store_class(this_module, "store"); + + store_class.def(python::constructor()); + store_class.def(&store::recall, "recall"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp new file mode 100644 index 00000000..529c9f42 --- /dev/null +++ b/example/noncopyable_import.cpp @@ -0,0 +1,42 @@ +#include +#include +namespace python = boost::python; + +#include "store.h" + +namespace { // Avoid cluttering the global namespace. + + // A function with store objects as both input and output parameters. + // Because the copy constructor is disabled, we cannot pass a store + // object by value. Instead, we pass a smart pointer. + std::auto_ptr add_stores(const store& s1, const store& s2) + { + int sum = s1.recall() + s2.recall(); + std::auto_ptr ss = std::auto_ptr(new store(sum)); + return ss; + } +} + +extern "C" +DL_EXPORT(void) +initnoncopyable_import() +{ + try + { + python::module_builder this_module("noncopyable_import"); + + python::import_class_builder + dvect_class("noncopyable_export", "store"); + + // Imagine all the additional classes with member functions + // that have store objects as input and output parameters. + // Lots and lots of them. + // However, to keep this example simple, we only define a + // module-level function. + this_module.def(add_stores, "add_stores"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/store.h b/example/store.h new file mode 100644 index 00000000..74ef0477 --- /dev/null +++ b/example/store.h @@ -0,0 +1,14 @@ +#ifndef STORE_H +#define STORE_H + +class store +{ + private: + store(const store&) { } // Disable the copy constructor. + int number; + public: + store(const int i) : number(i) { } + int recall() const { return number; } +}; + +#endif // STORE_H diff --git a/example/tst_dvect.py b/example/tst_dvect.py new file mode 100644 index 00000000..563f0ad5 --- /dev/null +++ b/example/tst_dvect.py @@ -0,0 +1,16 @@ +import dvect +print dvect.dvect.__converters__ +dv = dvect.dvect((1,2,3,4,5)) +print dv +print dv.as_tuple() +iv = dv.as_ivect() +print iv +print iv.as_tuple() +print dvect.ivect_as_tuple(iv) +aiv = dv.auto_ptr_ivect() +print aiv +siv = dv.shared_ptr_ivect() +print dvect.auto_ptr_ivect_as_tuple(aiv) +print dvect.ivect_as_tuple(aiv) +print dvect.shared_ptr_ivect_as_tuple(siv) +print dvect.ivect_as_tuple(siv) diff --git a/example/tst_ivect.py b/example/tst_ivect.py new file mode 100644 index 00000000..58bc323f --- /dev/null +++ b/example/tst_ivect.py @@ -0,0 +1,16 @@ +import ivect +print ivect.ivect.__converters__ +iv = ivect.ivect((1,2,3,4,5)) +print iv +print iv.as_tuple() +dv = iv.as_dvect() +print dv +print dv.as_tuple() +print ivect.dvect_as_tuple(dv) +adv = iv.auto_ptr_dvect() +print adv +sdv = iv.shared_ptr_dvect() +print ivect.auto_ptr_dvect_as_tuple(adv) +print ivect.dvect_as_tuple(adv) +print ivect.shared_ptr_dvect_as_tuple(sdv) +print ivect.dvect_as_tuple(sdv) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py new file mode 100644 index 00000000..913df039 --- /dev/null +++ b/example/tst_noncopyable.py @@ -0,0 +1,8 @@ +import noncopyable_export +import noncopyable_import +s1 = noncopyable_export.store(1) +print s1.recall() +s2 = noncopyable_export.store(2) +print s2.recall() +s3 = noncopyable_import.add_stores(s1, s2) +print s3.recall()