annotate DEPENDENCIES/generic/include/boost/mpi/python/serialize.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com>
Chris@16 2
Chris@16 3 // Use, modification and distribution is subject to the Boost Software
Chris@16 4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Authors: Douglas Gregor
Chris@16 8
Chris@16 9 /** @file serialize.hpp
Chris@16 10 *
Chris@16 11 * This file provides Boost.Serialization support for Python objects
Chris@16 12 * within Boost.MPI. Python objects can be serialized in one of two
Chris@16 13 * ways. The default serialization method involves using the Python
Chris@16 14 * "pickle" module to pickle the Python objects, transmits the
Chris@16 15 * pickled representation, and unpickles the result when
Chris@16 16 * received. For C++ types that have been exposed to Python and
Chris@16 17 * registered with register_serialized(), objects are directly
Chris@16 18 * serialized for transmissing, skipping the pickling step.
Chris@16 19 */
Chris@16 20 #ifndef BOOST_MPI_PYTHON_SERIALIZE_HPP
Chris@16 21 #define BOOST_MPI_PYTHON_SERIALIZE_HPP
Chris@16 22
Chris@16 23 #include <boost/mpi/python/config.hpp>
Chris@16 24
Chris@16 25 #include <boost/python/object.hpp>
Chris@16 26 #include <boost/python/str.hpp>
Chris@16 27 #include <boost/python/extract.hpp>
Chris@16 28
Chris@16 29 #include <memory>
Chris@16 30 #include <map>
Chris@16 31
Chris@16 32 #include <boost/function/function3.hpp>
Chris@16 33
Chris@16 34 #include <boost/mpl/bool.hpp>
Chris@16 35 #include <boost/mpl/if.hpp>
Chris@16 36
Chris@16 37 #include <boost/serialization/split_free.hpp>
Chris@16 38 #include <boost/serialization/array.hpp>
Chris@16 39
Chris@16 40 #include <boost/assert.hpp>
Chris@16 41
Chris@16 42 #include <boost/type_traits/is_fundamental.hpp>
Chris@16 43
Chris@16 44 #define BOOST_MPI_PYTHON_FORWARD_ONLY
Chris@16 45 #include <boost/mpi/python.hpp>
Chris@16 46
Chris@16 47 /************************************************************************
Chris@16 48 * Boost.Python Serialization Section *
Chris@16 49 ************************************************************************/
Chris@16 50 #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
Chris@16 51 /**
Chris@16 52 * @brief Declare IArchive and OArchive as a Boost.Serialization
Chris@16 53 * archives that can be used for Python objects.
Chris@16 54 *
Chris@16 55 * This macro can only be expanded from the global namespace. It only
Chris@16 56 * requires that Archiver be forward-declared. IArchiver and OArchiver
Chris@16 57 * will only support Serialization of Python objects by pickling
Chris@16 58 * them. If the Archiver type should also support "direct"
Chris@16 59 * serialization (for C++ types), use
Chris@16 60 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE instead.
Chris@16 61 */
Chris@16 62 # define BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver) \
Chris@16 63 namespace boost { namespace python { namespace api { \
Chris@16 64 template<typename R, typename T> \
Chris@16 65 struct enable_binary< IArchiver , R, T> {}; \
Chris@16 66 \
Chris@16 67 template<typename R, typename T> \
Chris@16 68 struct enable_binary< OArchiver , R, T> {}; \
Chris@16 69 } } }
Chris@16 70 # else
Chris@16 71 # define BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver)
Chris@16 72 #endif
Chris@16 73
Chris@16 74 /**
Chris@16 75 * @brief Declare IArchiver and OArchiver as a Boost.Serialization
Chris@16 76 * archives that can be used for Python objects and C++ objects
Chris@16 77 * wrapped in Python.
Chris@16 78 *
Chris@16 79 * This macro can only be expanded from the global namespace. It only
Chris@16 80 * requires that IArchiver and OArchiver be forward-declared. However,
Chris@16 81 * note that you will also need to write
Chris@16 82 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL(IArchiver,
Chris@16 83 * OArchiver) in one of your translation units.
Chris@16 84
Chris@16 85 DPG PICK UP HERE
Chris@16 86 */
Chris@16 87 #define BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(IArchiver, OArchiver) \
Chris@16 88 BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver) \
Chris@16 89 namespace boost { namespace python { namespace detail { \
Chris@16 90 template<> \
Chris@16 91 BOOST_MPI_PYTHON_DECL direct_serialization_table< IArchiver , OArchiver >& \
Chris@16 92 get_direct_serialization_table< IArchiver , OArchiver >(); \
Chris@16 93 } \
Chris@16 94 \
Chris@16 95 template<> \
Chris@16 96 struct has_direct_serialization< IArchiver , OArchiver> : mpl::true_ { }; \
Chris@16 97 \
Chris@16 98 template<> \
Chris@16 99 struct output_archiver< IArchiver > { typedef OArchiver type; }; \
Chris@16 100 \
Chris@16 101 template<> \
Chris@16 102 struct input_archiver< OArchiver > { typedef IArchiver type; }; \
Chris@16 103 } }
Chris@16 104
Chris@16 105 /**
Chris@16 106 * @brief Define the implementation for Boost.Serialization archivers
Chris@16 107 * that can be used for Python objects and C++ objects wrapped in
Chris@16 108 * Python.
Chris@16 109 *
Chris@16 110 * This macro can only be expanded from the global namespace. It only
Chris@16 111 * requires that IArchiver and OArchiver be forward-declared. Before
Chris@16 112 * using this macro, you will need to declare IArchiver and OArchiver
Chris@16 113 * as direct serialization archives with
Chris@16 114 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(IArchiver, OArchiver).
Chris@16 115 */
Chris@16 116 #define BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL(IArchiver, OArchiver) \
Chris@16 117 namespace boost { namespace python { namespace detail { \
Chris@16 118 template \
Chris@16 119 class BOOST_MPI_PYTHON_DECL direct_serialization_table< IArchiver , OArchiver >; \
Chris@16 120 \
Chris@16 121 template<> \
Chris@16 122 BOOST_MPI_PYTHON_DECL \
Chris@16 123 direct_serialization_table< IArchiver , OArchiver >& \
Chris@16 124 get_direct_serialization_table< IArchiver , OArchiver >( ) \
Chris@16 125 { \
Chris@16 126 static direct_serialization_table< IArchiver, OArchiver > table; \
Chris@16 127 return table; \
Chris@16 128 } \
Chris@16 129 } } }
Chris@16 130
Chris@16 131 namespace boost { namespace python {
Chris@16 132
Chris@16 133 /**
Chris@16 134 * INTERNAL ONLY
Chris@16 135 *
Chris@16 136 * Provides access to the Python "pickle" module from within C++.
Chris@16 137 */
Chris@16 138 class BOOST_MPI_PYTHON_DECL pickle {
Chris@16 139 struct data_t;
Chris@16 140
Chris@16 141 public:
Chris@16 142 static str dumps(object obj, int protocol = -1);
Chris@16 143 static object loads(str s);
Chris@16 144
Chris@16 145 private:
Chris@16 146 static void initialize_data();
Chris@16 147
Chris@16 148 static data_t* data;
Chris@16 149 };
Chris@16 150
Chris@16 151 /**
Chris@16 152 * @brief Whether the input/output archiver pair has "direct"
Chris@16 153 * serialization for C++ objects exposed in Python.
Chris@16 154 *
Chris@16 155 * Users do not typically need to specialize this trait, as it will be
Chris@16 156 * specialized as part of the macro
Chris@16 157 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE.
Chris@16 158 */
Chris@16 159 template<typename IArchiver, typename OArchiver>
Chris@16 160 struct has_direct_serialization : mpl::false_ { };
Chris@16 161
Chris@16 162 /**
Chris@16 163 * @brief A metafunction that determines the output archiver for the
Chris@16 164 * given input archiver.
Chris@16 165 *
Chris@16 166 * Users do not typically need to specialize this trait, as it will be
Chris@16 167 * specialized as part of the macro
Chris@16 168 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE.
Chris@16 169 */
Chris@16 170 template<typename IArchiver> struct output_archiver { };
Chris@16 171
Chris@16 172 /**
Chris@16 173 * @brief A metafunction that determines the input archiver for the
Chris@16 174 * given output archiver.
Chris@16 175 *
Chris@16 176 * Users do not typically need to specialize this trait, as it will be
Chris@16 177 * specialized as part of the macro
Chris@16 178 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE.
Chris@16 179 *
Chris@16 180 */
Chris@16 181 template<typename OArchiver> struct input_archiver { };
Chris@16 182
Chris@16 183 namespace detail {
Chris@16 184
Chris@16 185 /**
Chris@16 186 * INTERNAL ONLY
Chris@16 187 *
Chris@16 188 * This class contains the direct-serialization code for the given
Chris@16 189 * IArchiver/OArchiver pair. It is intended to be used as a
Chris@16 190 * singleton class, and will be accessed when (de-)serializing a
Chris@16 191 * Boost.Python object with an archiver that supports direct
Chris@16 192 * serializations. Do not create instances of this class directly:
Chris@16 193 * instead, use get_direct_serialization_table.
Chris@16 194 */
Chris@16 195 template<typename IArchiver, typename OArchiver>
Chris@16 196 class BOOST_MPI_PYTHON_DECL direct_serialization_table
Chris@16 197 {
Chris@16 198 public:
Chris@16 199 typedef boost::function3<void, OArchiver&, const object&, const unsigned int>
Chris@16 200 saver_t;
Chris@16 201 typedef boost::function3<void, IArchiver&, object&, const unsigned int>
Chris@16 202 loader_t;
Chris@16 203
Chris@16 204 typedef std::map<PyTypeObject*, std::pair<int, saver_t> > savers_t;
Chris@16 205 typedef std::map<int, loader_t> loaders_t;
Chris@16 206
Chris@16 207 /**
Chris@16 208 * Retrieve the saver (serializer) associated with the Python
Chris@16 209 * object @p obj.
Chris@16 210 *
Chris@16 211 * @param obj The object we want to save. Only its (Python) type
Chris@16 212 * is important.
Chris@16 213 *
Chris@16 214 * @param descriptor The value of the descriptor associated to
Chris@16 215 * the returned saver. Will be set to zero if no saver was found
Chris@16 216 * for @p obj.
Chris@16 217 *
Chris@16 218 * @returns a function object that can be used to serialize this
Chris@16 219 * object (and other objects of the same type), if possible. If
Chris@16 220 * no saver can be found, returns an empty function object..
Chris@16 221 */
Chris@16 222 saver_t saver(const object& obj, int& descriptor)
Chris@16 223 {
Chris@16 224 typename savers_t::iterator pos = savers.find(obj.ptr()->ob_type);
Chris@16 225 if (pos != savers.end()) {
Chris@16 226 descriptor = pos->second.first;
Chris@16 227 return pos->second.second;
Chris@16 228 }
Chris@16 229 else {
Chris@16 230 descriptor = 0;
Chris@16 231 return saver_t();
Chris@16 232 }
Chris@16 233 }
Chris@16 234
Chris@16 235 /**
Chris@16 236 * Retrieve the loader (deserializer) associated with the given
Chris@16 237 * descriptor.
Chris@16 238 *
Chris@16 239 * @param descriptor The descriptor number provided by saver()
Chris@16 240 * when determining the saver for this type.
Chris@16 241 *
Chris@16 242 * @returns a function object that can be used to deserialize an
Chris@16 243 * object whose type is the same as that corresponding to the
Chris@16 244 * descriptor. If the descriptor is unknown, the return value
Chris@16 245 * will be an empty function object.
Chris@16 246 */
Chris@16 247 loader_t loader(int descriptor)
Chris@16 248 {
Chris@16 249 typename loaders_t::iterator pos = loaders.find(descriptor);
Chris@16 250 if (pos != loaders.end())
Chris@16 251 return pos->second;
Chris@16 252 else
Chris@16 253 return loader_t();
Chris@16 254 }
Chris@16 255
Chris@16 256 /**
Chris@16 257 * Register the type T for direct serialization.
Chris@16 258 *
Chris@16 259 * @param value A sample value of the type @c T. This may be used
Chris@16 260 * to compute the Python type associated with the C++ type @c T.
Chris@16 261 *
Chris@16 262 * @param type The Python type associated with the C++ type @c
Chris@16 263 * T. If not provided, it will be computed from the same value @p
Chris@16 264 * value.
Chris@16 265 */
Chris@16 266 template<typename T>
Chris@16 267 void register_type(const T& value = T(), PyTypeObject* type = 0)
Chris@16 268 {
Chris@16 269 // If the user did not provide us with a Python type, figure it
Chris@16 270 // out for ourselves.
Chris@16 271 if (!type) {
Chris@16 272 object obj(value);
Chris@16 273 type = obj.ptr()->ob_type;
Chris@16 274 }
Chris@16 275
Chris@16 276 register_type(default_saver<T>(), default_loader<T>(type), value, type);
Chris@16 277 }
Chris@16 278
Chris@16 279 /**
Chris@16 280 * Register the type T for direct serialization.
Chris@16 281 *
Chris@16 282 * @param saver A function object that will serialize a
Chris@16 283 * Boost.Python object (that represents a C++ object of type @c
Chris@16 284 * T) to an @c OArchive.
Chris@16 285 *
Chris@16 286 * @param loader A function object that will deserialize from an
Chris@16 287 * @c IArchive into a Boost.Python object that represents a C++
Chris@16 288 * object of type @c T.
Chris@16 289 *
Chris@16 290 * @param value A sample value of the type @c T. This may be used
Chris@16 291 * to compute the Python type associated with the C++ type @c T.
Chris@16 292 *
Chris@16 293 * @param type The Python type associated with the C++ type @c
Chris@16 294 * T. If not provided, it will be computed from the same value @p
Chris@16 295 * value.
Chris@16 296 */
Chris@16 297 template<typename T>
Chris@16 298 void register_type(const saver_t& saver, const loader_t& loader,
Chris@16 299 const T& value = T(), PyTypeObject* type = 0)
Chris@16 300 {
Chris@16 301 // If the user did not provide us with a Python type, figure it
Chris@16 302 // out for ourselves.
Chris@16 303 if (!type) {
Chris@16 304 object obj(value);
Chris@16 305 type = obj.ptr()->ob_type;
Chris@16 306 }
Chris@16 307
Chris@16 308 int descriptor = savers.size() + 1;
Chris@16 309 if (savers.find(type) != savers.end())
Chris@16 310 return;
Chris@16 311
Chris@16 312 savers[type] = std::make_pair(descriptor, saver);
Chris@16 313 loaders[descriptor] = loader;
Chris@16 314 }
Chris@16 315
Chris@16 316 protected:
Chris@16 317 template<typename T>
Chris@16 318 struct default_saver {
Chris@16 319 void operator()(OArchiver& ar, const object& obj, const unsigned int) {
Chris@16 320 T value = extract<T>(obj)();
Chris@16 321 ar << value;
Chris@16 322 }
Chris@16 323 };
Chris@16 324
Chris@16 325 template<typename T>
Chris@16 326 struct default_loader {
Chris@16 327 default_loader(PyTypeObject* type) : type(type) { }
Chris@16 328
Chris@16 329 void operator()(IArchiver& ar, object& obj, const unsigned int) {
Chris@16 330 // If we can, extract the object in place.
Chris@16 331 if (!is_fundamental<T>::value && obj && obj.ptr()->ob_type == type) {
Chris@16 332 ar >> extract<T&>(obj)();
Chris@16 333 } else {
Chris@16 334 T value;
Chris@16 335 ar >> value;
Chris@16 336 obj = object(value);
Chris@16 337 }
Chris@16 338 }
Chris@16 339
Chris@16 340 private:
Chris@16 341 PyTypeObject* type;
Chris@16 342 };
Chris@16 343
Chris@16 344 savers_t savers;
Chris@16 345 loaders_t loaders;
Chris@16 346 };
Chris@16 347
Chris@16 348 /**
Chris@16 349 * @brief Retrieve the direct-serialization table for an
Chris@16 350 * IArchiver/OArchiver pair.
Chris@16 351 *
Chris@16 352 * This function is responsible for returning a reference to the
Chris@16 353 * singleton direct-serialization table. Its primary template is
Chris@16 354 * left undefined, to force the use of an explicit specialization
Chris@16 355 * with a definition in a single translation unit. Use the macro
Chris@16 356 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL to define this
Chris@16 357 * explicit specialization.
Chris@16 358 */
Chris@16 359 template<typename IArchiver, typename OArchiver>
Chris@16 360 direct_serialization_table<IArchiver, OArchiver>&
Chris@16 361 get_direct_serialization_table();
Chris@16 362 } // end namespace detail
Chris@16 363
Chris@16 364 /**
Chris@16 365 * @brief Register the type T for direct serialization.
Chris@16 366 *
Chris@16 367 * The @c register_serialized function registers a C++ type for direct
Chris@16 368 * serialization with the given @c IArchiver/@c OArchiver pair. Direct
Chris@16 369 * serialization elides the use of the Python @c pickle package when
Chris@16 370 * serializing Python objects that represent C++ values. Direct
Chris@16 371 * serialization can be beneficial both to improve serialization
Chris@16 372 * performance (Python pickling can be very inefficient) and to permit
Chris@16 373 * serialization for Python-wrapped C++ objects that do not support
Chris@16 374 * pickling.
Chris@16 375 *
Chris@16 376 * @param value A sample value of the type @c T. This may be used
Chris@16 377 * to compute the Python type associated with the C++ type @c T.
Chris@16 378 *
Chris@16 379 * @param type The Python type associated with the C++ type @c
Chris@16 380 * T. If not provided, it will be computed from the same value @p
Chris@16 381 * value.
Chris@16 382 */
Chris@16 383 template<typename IArchiver, typename OArchiver, typename T>
Chris@16 384 void
Chris@16 385 register_serialized(const T& value = T(), PyTypeObject* type = 0)
Chris@16 386 {
Chris@16 387 detail::direct_serialization_table<IArchiver, OArchiver>& table =
Chris@16 388 detail::get_direct_serialization_table<IArchiver, OArchiver>();
Chris@16 389 table.register_type(value, type);
Chris@16 390 }
Chris@16 391
Chris@16 392 namespace detail {
Chris@16 393
Chris@16 394 /// Save a Python object by pickling it.
Chris@16 395 template<typename Archiver>
Chris@16 396 void
Chris@16 397 save_impl(Archiver& ar, const boost::python::object& obj,
Chris@16 398 const unsigned int /*version*/,
Chris@16 399 mpl::false_ /*has_direct_serialization*/)
Chris@16 400 {
Chris@16 401 boost::python::str py_string = boost::python::pickle::dumps(obj);
Chris@16 402 int len = boost::python::extract<int>(py_string.attr("__len__")());
Chris@16 403 const char* string = boost::python::extract<const char*>(py_string);
Chris@16 404 ar << len << boost::serialization::make_array(string, len);
Chris@16 405 }
Chris@16 406
Chris@16 407 /// Try to save a Python object by directly serializing it; fall back
Chris@16 408 /// on pickling if required.
Chris@16 409 template<typename Archiver>
Chris@16 410 void
Chris@16 411 save_impl(Archiver& ar, const boost::python::object& obj,
Chris@16 412 const unsigned int version,
Chris@16 413 mpl::true_ /*has_direct_serialization*/)
Chris@16 414 {
Chris@16 415 typedef Archiver OArchiver;
Chris@16 416 typedef typename input_archiver<OArchiver>::type IArchiver;
Chris@16 417 typedef typename direct_serialization_table<IArchiver, OArchiver>::saver_t
Chris@16 418 saver_t;
Chris@16 419
Chris@16 420 direct_serialization_table<IArchiver, OArchiver>& table =
Chris@16 421 get_direct_serialization_table<IArchiver, OArchiver>();
Chris@16 422
Chris@16 423 int descriptor = 0;
Chris@16 424 if (saver_t saver = table.saver(obj, descriptor)) {
Chris@16 425 ar << descriptor;
Chris@16 426 saver(ar, obj, version);
Chris@16 427 } else {
Chris@16 428 // Pickle it
Chris@16 429 ar << descriptor;
Chris@16 430 detail::save_impl(ar, obj, version, mpl::false_());
Chris@16 431 }
Chris@16 432 }
Chris@16 433
Chris@16 434 /// Load a Python object by unpickling it
Chris@16 435 template<typename Archiver>
Chris@16 436 void
Chris@16 437 load_impl(Archiver& ar, boost::python::object& obj,
Chris@16 438 const unsigned int /*version*/,
Chris@16 439 mpl::false_ /*has_direct_serialization*/)
Chris@16 440 {
Chris@16 441 int len;
Chris@16 442 ar >> len;
Chris@16 443
Chris@16 444 std::auto_ptr<char> string(new char[len]);
Chris@16 445 ar >> boost::serialization::make_array(string.get(), len);
Chris@16 446 boost::python::str py_string(string.get(), len);
Chris@16 447 obj = boost::python::pickle::loads(py_string);
Chris@16 448 }
Chris@16 449
Chris@16 450 /// Try to load a Python object by directly deserializing it; fall back
Chris@16 451 /// on unpickling if required.
Chris@16 452 template<typename Archiver>
Chris@16 453 void
Chris@16 454 load_impl(Archiver& ar, boost::python::object& obj,
Chris@16 455 const unsigned int version,
Chris@16 456 mpl::true_ /*has_direct_serialization*/)
Chris@16 457 {
Chris@16 458 typedef Archiver IArchiver;
Chris@16 459 typedef typename output_archiver<IArchiver>::type OArchiver;
Chris@16 460 typedef typename direct_serialization_table<IArchiver, OArchiver>::loader_t
Chris@16 461 loader_t;
Chris@16 462
Chris@16 463 direct_serialization_table<IArchiver, OArchiver>& table =
Chris@16 464 get_direct_serialization_table<IArchiver, OArchiver>();
Chris@16 465
Chris@16 466 int descriptor;
Chris@16 467 ar >> descriptor;
Chris@16 468
Chris@16 469 if (descriptor) {
Chris@16 470 loader_t loader = table.loader(descriptor);
Chris@16 471 BOOST_ASSERT(loader);
Chris@16 472
Chris@16 473 loader(ar, obj, version);
Chris@16 474 } else {
Chris@16 475 // Unpickle it
Chris@16 476 detail::load_impl(ar, obj, version, mpl::false_());
Chris@16 477 }
Chris@16 478 }
Chris@16 479
Chris@16 480 } // end namespace detail
Chris@16 481
Chris@16 482 template<typename Archiver>
Chris@16 483 void
Chris@16 484 save(Archiver& ar, const boost::python::object& obj,
Chris@16 485 const unsigned int version)
Chris@16 486 {
Chris@16 487 typedef Archiver OArchiver;
Chris@16 488 typedef typename input_archiver<OArchiver>::type IArchiver;
Chris@16 489
Chris@16 490 detail::save_impl(ar, obj, version,
Chris@16 491 has_direct_serialization<IArchiver, OArchiver>());
Chris@16 492 }
Chris@16 493
Chris@16 494 template<typename Archiver>
Chris@16 495 void
Chris@16 496 load(Archiver& ar, boost::python::object& obj,
Chris@16 497 const unsigned int version)
Chris@16 498 {
Chris@16 499 typedef Archiver IArchiver;
Chris@16 500 typedef typename output_archiver<IArchiver>::type OArchiver;
Chris@16 501
Chris@16 502 detail::load_impl(ar, obj, version,
Chris@16 503 has_direct_serialization<IArchiver, OArchiver>());
Chris@16 504 }
Chris@16 505
Chris@16 506 template<typename Archive>
Chris@16 507 inline void
Chris@16 508 serialize(Archive& ar, boost::python::object& obj, const unsigned int version)
Chris@16 509 {
Chris@16 510 boost::serialization::split_free(ar, obj, version);
Chris@16 511 }
Chris@16 512
Chris@16 513 } } // end namespace boost::python
Chris@16 514
Chris@16 515 /************************************************************************
Chris@16 516 * Boost.MPI-Specific Section *
Chris@16 517 ************************************************************************/
Chris@16 518 namespace boost { namespace mpi {
Chris@16 519 class packed_iarchive;
Chris@16 520 class packed_oarchive;
Chris@16 521 } } // end namespace boost::mpi
Chris@16 522
Chris@16 523 BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(
Chris@16 524 ::boost::mpi::packed_iarchive,
Chris@16 525 ::boost::mpi::packed_oarchive)
Chris@16 526
Chris@16 527 namespace boost { namespace mpi { namespace python {
Chris@16 528
Chris@16 529 template<typename T>
Chris@16 530 void
Chris@16 531 register_serialized(const T& value, PyTypeObject* type)
Chris@16 532 {
Chris@16 533 using boost::python::register_serialized;
Chris@16 534 register_serialized<packed_iarchive, packed_oarchive>(value, type);
Chris@16 535 }
Chris@16 536
Chris@16 537 } } } // end namespace boost::mpi::python
Chris@16 538
Chris@16 539 #endif // BOOST_MPI_PYTHON_SERIALIZE_HPP