serialize.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 540 行 · 第 1/2 页

HPP
540
字号
// Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com>// Use, modification and distribution is subject to the Boost Software// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//  Authors: Douglas Gregor/** @file serialize.hpp * *  This file provides Boost.Serialization support for Python objects *  within Boost.MPI. Python objects can be serialized in one of two *  ways. The default serialization method involves using the Python *  "pickle" module to pickle the Python objects, transmits the *  pickled representation, and unpickles the result when *  received. For C++ types that have been exposed to Python and *  registered with register_serialized(), objects are directly *  serialized for transmissing, skipping the pickling step. */#ifndef BOOST_MPI_PYTHON_SERIALIZE_HPP#define BOOST_MPI_PYTHON_SERIALIZE_HPP#include <boost/mpi/python/config.hpp>#include <boost/python/object.hpp>#include <boost/python/str.hpp>#include <boost/python/extract.hpp>#include <memory>#include <map>#include <boost/function/function3.hpp>#include <boost/mpl/bool.hpp>#include <boost/mpl/if.hpp>#include <boost/serialization/split_free.hpp>#include <boost/serialization/array.hpp>#include <boost/assert.hpp>#include <boost/type_traits/is_fundamental.hpp>#define BOOST_MPI_PYTHON_FORWARD_ONLY#include <boost/mpi/python.hpp>/************************************************************************ * Boost.Python Serialization Section                                   * ************************************************************************/#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)/** * @brief Declare IArchive and OArchive as a Boost.Serialization * archives that can be used for Python objects. * * This macro can only be expanded from the global namespace. It only * requires that Archiver be forward-declared. IArchiver and OArchiver * will only support Serialization of Python objects by pickling * them. If the Archiver type should also support "direct" * serialization (for C++ types), use * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE instead. */#  define BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver)        \namespace boost { namespace python { namespace api {    \  template<typename R, typename T>                      \  struct enable_binary< IArchiver , R, T> {};           \                                                        \  template<typename R, typename T>                      \  struct enable_binary< OArchiver , R, T> {};           \} } } # else#  define BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver)#endif/** * @brief Declare IArchiver and OArchiver as a Boost.Serialization * archives that can be used for Python objects and C++ objects * wrapped in Python. * * This macro can only be expanded from the global namespace. It only * requires that IArchiver and OArchiver be forward-declared. However, * note that you will also need to write * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL(IArchiver, * OArchiver) in one of your translation units.DPG PICK UP HERE */#define BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(IArchiver, OArchiver) \BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver)                \namespace boost { namespace python { namespace detail {                 \template<>                                                              \BOOST_MPI_PYTHON_DECL direct_serialization_table< IArchiver , OArchiver >& \ get_direct_serialization_table< IArchiver , OArchiver >();             \}                                                                       \                                                                        \template<>                                                              \struct has_direct_serialization< IArchiver , OArchiver> : mpl::true_ { }; \                                                                        \template<>                                                              \struct output_archiver< IArchiver > { typedef OArchiver type; };        \                                                                        \template<>                                                              \struct input_archiver< OArchiver > { typedef IArchiver type; };         \} }/** * @brief Define the implementation for Boost.Serialization archivers * that can be used for Python objects and C++ objects wrapped in * Python. * * This macro can only be expanded from the global namespace. It only * requires that IArchiver and OArchiver be forward-declared. Before * using this macro, you will need to declare IArchiver and OArchiver * as direct serialization archives with * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(IArchiver, OArchiver). */#define BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL(IArchiver, OArchiver) \namespace boost { namespace python { namespace detail {                 \template                                                                \  class BOOST_MPI_PYTHON_DECL direct_serialization_table< IArchiver , OArchiver >; \                                                                        \template<>                                                              \ BOOST_MPI_PYTHON_DECL                                                  \ direct_serialization_table< IArchiver , OArchiver >&                   \ get_direct_serialization_table< IArchiver , OArchiver >( )             \{                                                                       \  static direct_serialization_table< IArchiver, OArchiver > table;      \  return table;                                                         \}                                                                       \} } }namespace boost { namespace python {/** * INTERNAL ONLY * * Provides access to the Python "pickle" module from within C++. */class BOOST_MPI_PYTHON_DECL pickle {  struct data_t;public:  static str dumps(object obj, int protocol = -1);  static object loads(str s);  private:  static void initialize_data();  static data_t* data;};/** * @brief Whether the input/output archiver pair has "direct" * serialization for C++ objects exposed in Python. * * Users do not typically need to specialize this trait, as it will be * specialized as part of the macro * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE. */template<typename IArchiver, typename OArchiver>struct has_direct_serialization : mpl::false_ { };/** *  @brief A metafunction that determines the output archiver for the *  given input archiver. * * Users do not typically need to specialize this trait, as it will be * specialized as part of the macro * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE. */template<typename IArchiver> struct output_archiver { };/** *  @brief A metafunction that determines the input archiver for the *  given output archiver. * * Users do not typically need to specialize this trait, as it will be * specialized as part of the macro * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE. * */template<typename OArchiver> struct input_archiver { };namespace detail {  /**   * INTERNAL ONLY   *   * This class contains the direct-serialization code for the given   * IArchiver/OArchiver pair. It is intended to be used as a   * singleton class, and will be accessed when (de-)serializing a   * Boost.Python object with an archiver that supports direct   * serializations. Do not create instances of this class directly:   * instead, use get_direct_serialization_table.   */  template<typename IArchiver, typename OArchiver>  class BOOST_MPI_PYTHON_DECL direct_serialization_table  {  public:    typedef boost::function3<void, OArchiver&, const object&, const unsigned int>      saver_t;    typedef boost::function3<void, IArchiver&, object&, const unsigned int>      loader_t;    typedef std::map<PyTypeObject*, std::pair<int, saver_t> > savers_t;    typedef std::map<int, loader_t> loaders_t;    /**     * Retrieve the saver (serializer) associated with the Python     * object @p obj.     *     *   @param obj The object we want to save. Only its (Python) type     *   is important.     *     *   @param descriptor The value of the descriptor associated to     *   the returned saver. Will be set to zero if no saver was found     *   for @p obj.     *     *   @returns a function object that can be used to serialize this     *   object (and other objects of the same type), if possible. If     *   no saver can be found, returns an empty function object..     */    saver_t saver(const object& obj, int& descriptor)    {      typename savers_t::iterator pos = savers.find(obj.ptr()->ob_type);      if (pos != savers.end()) {        descriptor = pos->second.first;        return pos->second.second;      }      else {        descriptor = 0;        return saver_t();      }    }    /**     * Retrieve the loader (deserializer) associated with the given     * descriptor.     *     *  @param descriptor The descriptor number provided by saver()     *  when determining the saver for this type.     *     *  @returns a function object that can be used to deserialize an     *  object whose type is the same as that corresponding to the     *  descriptor. If the descriptor is unknown, the return value     *  will be an empty function object.     */    loader_t loader(int descriptor)    {      typename loaders_t::iterator pos = loaders.find(descriptor);      if (pos != loaders.end())        return pos->second;      else        return loader_t();    }    /**     * Register the type T for direct serialization.     *     *  @param value A sample value of the type @c T. This may be used     *  to compute the Python type associated with the C++ type @c T.     *     *  @param type The Python type associated with the C++ type @c     *  T. If not provided, it will be computed from the same value @p     *  value.     */    template<typename T>    void register_type(const T& value = T(), PyTypeObject* type = 0)    {      // If the user did not provide us with a Python type, figure it      // out for ourselves.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?