File indexing completed on 2025-01-18 09:40:58
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MPI_PYTHON_SKELETON_AND_CONTENT_HPP
0009 #define BOOST_MPI_PYTHON_SKELETON_AND_CONTENT_HPP
0010
0011
0012
0013
0014
0015 #include <boost/python.hpp>
0016 #include <boost/mpi.hpp>
0017 #include <boost/function/function1.hpp>
0018 #define BOOST_MPI_PYTHON_FORWARD_ONLY
0019 #include <boost/mpi/python.hpp>
0020 #include <boost/mpi/python/serialize.hpp>
0021
0022
0023 namespace boost { namespace mpi { namespace python {
0024
0025
0026
0027
0028
0029
0030
0031
0032 class content : public boost::mpi::content
0033 {
0034 typedef boost::mpi::content inherited;
0035
0036 public:
0037 content(const inherited& base, boost::python::object object)
0038 : inherited(base), object(object) { }
0039
0040 inherited& base() { return *this; }
0041 const inherited& base() const { return *this; }
0042
0043 boost::python::object object;
0044 };
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 class skeleton_proxy_base
0058 {
0059 public:
0060 skeleton_proxy_base(const boost::python::object& object) : object(object) { }
0061
0062 boost::python::object object;
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 template<typename T>
0075 class skeleton_proxy : public skeleton_proxy_base
0076 {
0077 public:
0078 skeleton_proxy(const boost::python::object& object)
0079 : skeleton_proxy_base(object) { }
0080 };
0081
0082 namespace detail {
0083 using boost::python::object;
0084 using boost::python::extract;
0085
0086 extern BOOST_MPI_DECL boost::python::object skeleton_proxy_base_type;
0087
0088 template<typename T>
0089 struct skeleton_saver
0090 {
0091 void
0092 operator()(packed_oarchive& ar, const object& obj, const unsigned int)
0093 {
0094 packed_skeleton_oarchive pso(ar);
0095 pso << extract<T&>(obj.attr("object"))();
0096 }
0097 };
0098
0099 template<typename T>
0100 struct skeleton_loader
0101 {
0102 void
0103 operator()(packed_iarchive& ar, object& obj, const unsigned int)
0104 {
0105 packed_skeleton_iarchive psi(ar);
0106 extract<skeleton_proxy<T>&> proxy(obj);
0107 if (!proxy.check())
0108 obj = object(skeleton_proxy<T>(object(T())));
0109
0110 psi >> extract<T&>(obj.attr("object"))();
0111 }
0112 };
0113
0114
0115
0116
0117
0118
0119 struct skeleton_content_handler {
0120 function1<object, const object&> get_skeleton_proxy;
0121 function1<content, const object&> get_content;
0122 };
0123
0124
0125
0126
0127
0128 template<typename T>
0129 struct do_get_skeleton_proxy
0130 {
0131 object operator()(object value) {
0132 return object(skeleton_proxy<T>(value));
0133 }
0134 };
0135
0136
0137
0138
0139
0140 template<typename T>
0141 struct do_get_content
0142 {
0143 content operator()(object value_obj) {
0144 T& value = extract<T&>(value_obj)();
0145 return content(boost::mpi::get_content(value), value_obj);
0146 }
0147 };
0148
0149
0150
0151
0152
0153 BOOST_MPI_PYTHON_DECL bool
0154 skeleton_and_content_handler_registered(PyTypeObject* type);
0155
0156
0157
0158
0159
0160 BOOST_MPI_PYTHON_DECL void
0161 register_skeleton_and_content_handler(PyTypeObject*,
0162 const skeleton_content_handler&);
0163 }
0164
0165 template<typename T>
0166 void register_skeleton_and_content(const T& value, PyTypeObject* type)
0167 {
0168 using boost::python::detail::direct_serialization_table;
0169 using boost::python::detail::get_direct_serialization_table;
0170 using namespace boost::python;
0171
0172
0173 if (!type)
0174 type = object(value).ptr()->ob_type;
0175
0176
0177 if (detail::skeleton_and_content_handler_registered(type))
0178 return;
0179
0180
0181 {
0182 boost::python::scope proxy_scope(detail::skeleton_proxy_base_type);
0183 std::string name("skeleton_proxy<");
0184 name += typeid(T).name();
0185 name += ">";
0186 class_<skeleton_proxy<T>, bases<skeleton_proxy_base> >(name.c_str(),
0187 no_init);
0188 }
0189
0190
0191
0192 direct_serialization_table<packed_iarchive, packed_oarchive>& table =
0193 get_direct_serialization_table<packed_iarchive, packed_oarchive>();
0194 table.register_type(detail::skeleton_saver<T>(),
0195 detail::skeleton_loader<T>(),
0196 skeleton_proxy<T>(object(value)));
0197
0198
0199
0200
0201 detail::skeleton_content_handler handler;
0202 handler.get_skeleton_proxy = detail::do_get_skeleton_proxy<T>();
0203 handler.get_content = detail::do_get_content<T>();
0204 detail::register_skeleton_and_content_handler(type, handler);
0205 }
0206
0207 } } }
0208
0209 #endif