123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- #ifndef BOOST_MPI_PYTHON_SKELETON_AND_CONTENT_HPP
- #define BOOST_MPI_PYTHON_SKELETON_AND_CONTENT_HPP
- #include <boost/python.hpp>
- #include <boost/mpi.hpp>
- #include <boost/function/function1.hpp>
- #define BOOST_MPI_PYTHON_FORWARD_ONLY
- #include <boost/mpi/python.hpp>
- #include <boost/mpi/python/serialize.hpp>
- namespace boost { namespace mpi { namespace python {
- class content : public boost::mpi::content
- {
- typedef boost::mpi::content inherited;
- public:
- content(const inherited& base, boost::python::object object)
- : inherited(base), object(object) { }
- inherited& base() { return *this; }
- const inherited& base() const { return *this; }
- boost::python::object object;
- };
- class skeleton_proxy_base
- {
- public:
- skeleton_proxy_base(const boost::python::object& object) : object(object) { }
- boost::python::object object;
- };
- template<typename T>
- class skeleton_proxy : public skeleton_proxy_base
- {
- public:
- skeleton_proxy(const boost::python::object& object)
- : skeleton_proxy_base(object) { }
- };
- namespace detail {
- using boost::python::object;
- using boost::python::extract;
-
- extern BOOST_MPI_DECL boost::python::object skeleton_proxy_base_type;
- template<typename T>
- struct skeleton_saver
- {
- void
- operator()(packed_oarchive& ar, const object& obj, const unsigned int)
- {
- packed_skeleton_oarchive pso(ar);
- pso << extract<T&>(obj.attr("object"))();
- }
- };
- template<typename T>
- struct skeleton_loader
- {
- void
- operator()(packed_iarchive& ar, object& obj, const unsigned int)
- {
- packed_skeleton_iarchive psi(ar);
- extract<skeleton_proxy<T>&> proxy(obj);
- if (!proxy.check())
- obj = object(skeleton_proxy<T>(object(T())));
- psi >> extract<T&>(obj.attr("object"))();
- }
- };
-
- struct skeleton_content_handler {
- function1<object, const object&> get_skeleton_proxy;
- function1<content, const object&> get_content;
- };
-
- template<typename T>
- struct do_get_skeleton_proxy
- {
- object operator()(object value) {
- return object(skeleton_proxy<T>(value));
- }
- };
-
- template<typename T>
- struct do_get_content
- {
- content operator()(object value_obj) {
- T& value = extract<T&>(value_obj)();
- return content(boost::mpi::get_content(value), value_obj);
- }
- };
-
- BOOST_MPI_PYTHON_DECL bool
- skeleton_and_content_handler_registered(PyTypeObject* type);
-
-
- BOOST_MPI_PYTHON_DECL void
- register_skeleton_and_content_handler(PyTypeObject*,
- const skeleton_content_handler&);
- }
- template<typename T>
- void register_skeleton_and_content(const T& value, PyTypeObject* type)
- {
- using boost::python::detail::direct_serialization_table;
- using boost::python::detail::get_direct_serialization_table;
- using namespace boost::python;
-
- if (!type)
- type = object(value).ptr()->ob_type;
-
- if (detail::skeleton_and_content_handler_registered(type))
- return;
-
- {
- boost::python::scope proxy_scope(detail::skeleton_proxy_base_type);
- std::string name("skeleton_proxy<");
- name += typeid(T).name();
- name += ">";
- class_<skeleton_proxy<T>, bases<skeleton_proxy_base> >(name.c_str(),
- no_init);
- }
-
-
- direct_serialization_table<packed_iarchive, packed_oarchive>& table =
- get_direct_serialization_table<packed_iarchive, packed_oarchive>();
- table.register_type(detail::skeleton_saver<T>(),
- detail::skeleton_loader<T>(),
- skeleton_proxy<T>(object(value)));
-
-
-
- detail::skeleton_content_handler handler;
- handler.get_skeleton_proxy = detail::do_get_skeleton_proxy<T>();
- handler.get_content = detail::do_get_content<T>();
- detail::register_skeleton_and_content_handler(type, handler);
- }
- } } }
- #endif
|