serialize.hpp

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

HPP
540
字号
      if (!type) {        object obj(value);        type = obj.ptr()->ob_type;      }      register_type(default_saver<T>(), default_loader<T>(type), value, type);    }    /**     * Register the type T for direct serialization.     *     *  @param saver A function object that will serialize a     *  Boost.Python object (that represents a C++ object of type @c     *  T) to an @c OArchive.     *     *  @param loader A function object that will deserialize from an     *  @c IArchive into a Boost.Python object that represents a C++     *  object of type @c T.     *     *  @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 saver_t& saver, const loader_t& loader,                        const T& value = T(), PyTypeObject* type = 0)    {      // If the user did not provide us with a Python type, figure it      // out for ourselves.      if (!type) {        object obj(value);        type = obj.ptr()->ob_type;      }      int descriptor = savers.size() + 1;      if (savers.find(type) != savers.end())        return;      savers[type] = std::make_pair(descriptor, saver);      loaders[descriptor] = loader;    }  protected:    template<typename T>    struct default_saver {      void operator()(OArchiver& ar, const object& obj, const unsigned int) {        T value = extract<T>(obj)();        ar << value;      }    };    template<typename T>    struct default_loader {      default_loader(PyTypeObject* type) : type(type) { }      void operator()(IArchiver& ar, object& obj, const unsigned int) {        // If we can, extract the object in place.        if (!is_fundamental<T>::value && obj && obj.ptr()->ob_type == type) {          ar >> extract<T&>(obj)();        } else {          T value;          ar >> value;          obj = object(value);        }      }    private:      PyTypeObject* type;    };    savers_t savers;    loaders_t loaders;  };  /**   * @brief Retrieve the direct-serialization table for an   * IArchiver/OArchiver pair.   *   * This function is responsible for returning a reference to the   * singleton direct-serialization table. Its primary template is   * left undefined, to force the use of an explicit specialization   * with a definition in a single translation unit. Use the macro   * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL to define this   * explicit specialization.   */  template<typename IArchiver, typename OArchiver>  direct_serialization_table<IArchiver, OArchiver>&  get_direct_serialization_table();} // end namespace detail /** * @brief Register the type T for direct serialization. * * The @c register_serialized function registers a C++ type for direct * serialization with the given @c IArchiver/@c OArchiver pair. Direct * serialization elides the use of the Python @c pickle package when * serializing Python objects that represent C++ values. Direct * serialization can be beneficial both to improve serialization * performance (Python pickling can be very inefficient) and to permit * serialization for Python-wrapped C++ objects that do not support * pickling. * *  @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 IArchiver, typename OArchiver, typename T>voidregister_serialized(const T& value = T(), PyTypeObject* type = 0){  detail::direct_serialization_table<IArchiver, OArchiver>& table =     detail::get_direct_serialization_table<IArchiver, OArchiver>();  table.register_type(value, type);}namespace detail {/// Save a Python object by pickling it.template<typename Archiver>void save_impl(Archiver& ar, const boost::python::object& obj,           const unsigned int /*version*/,          mpl::false_ /*has_direct_serialization*/){  boost::python::str py_string = boost::python::pickle::dumps(obj);  int len = boost::python::extract<int>(py_string.attr("__len__")());  const char* string = boost::python::extract<const char*>(py_string);  ar << len << boost::serialization::make_array(string, len);}/// Try to save a Python object by directly serializing it; fall back/// on pickling if required.template<typename Archiver>void save_impl(Archiver& ar, const boost::python::object& obj,           const unsigned int version,          mpl::true_ /*has_direct_serialization*/){  typedef Archiver OArchiver;  typedef typename input_archiver<OArchiver>::type IArchiver;  typedef typename direct_serialization_table<IArchiver, OArchiver>::saver_t    saver_t;  direct_serialization_table<IArchiver, OArchiver>& table =     get_direct_serialization_table<IArchiver, OArchiver>();  int descriptor = 0;  if (saver_t saver = table.saver(obj, descriptor)) {    ar << descriptor;    saver(ar, obj, version);  } else {    // Pickle it    ar << descriptor;    detail::save_impl(ar, obj, version, mpl::false_());  }}/// Load a Python object by unpickling ittemplate<typename Archiver>void load_impl(Archiver& ar, boost::python::object& obj,           const unsigned int /*version*/,           mpl::false_ /*has_direct_serialization*/){  int len;  ar >> len;  std::auto_ptr<char> string(new char[len]);  ar >> boost::serialization::make_array(string.get(), len);  boost::python::str py_string(string.get(), len);  obj = boost::python::pickle::loads(py_string);}/// Try to load a Python object by directly deserializing it; fall back/// on unpickling if required.template<typename Archiver>void load_impl(Archiver& ar, boost::python::object& obj,           const unsigned int version,          mpl::true_ /*has_direct_serialization*/){  typedef Archiver IArchiver;  typedef typename output_archiver<IArchiver>::type OArchiver;  typedef typename direct_serialization_table<IArchiver, OArchiver>::loader_t    loader_t;  direct_serialization_table<IArchiver, OArchiver>& table =     get_direct_serialization_table<IArchiver, OArchiver>();  int descriptor;  ar >> descriptor;  if (descriptor) {    loader_t loader = table.loader(descriptor);    BOOST_ASSERT(loader);    loader(ar, obj, version);  } else {    // Unpickle it    detail::load_impl(ar, obj, version, mpl::false_());  }}} // end namespace detailtemplate<typename Archiver>void save(Archiver& ar, const boost::python::object& obj,      const unsigned int version){  typedef Archiver OArchiver;  typedef typename input_archiver<OArchiver>::type IArchiver;  detail::save_impl(ar, obj, version,                     has_direct_serialization<IArchiver, OArchiver>());}template<typename Archiver>void load(Archiver& ar, boost::python::object& obj,      const unsigned int version){  typedef Archiver IArchiver;  typedef typename output_archiver<IArchiver>::type OArchiver;  detail::load_impl(ar, obj, version,                     has_direct_serialization<IArchiver, OArchiver>());}template<typename Archive>inline void serialize(Archive& ar, boost::python::object& obj, const unsigned int version){  boost::serialization::split_free(ar, obj, version);}} } // end namespace boost::python/************************************************************************ * Boost.MPI-Specific Section                                           * ************************************************************************/namespace boost { namespace mpi { class packed_iarchive; class packed_oarchive;} } // end namespace boost::mpiBOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(  ::boost::mpi::packed_iarchive,  ::boost::mpi::packed_oarchive)namespace boost { namespace mpi { namespace python {template<typename T>voidregister_serialized(const T& value, PyTypeObject* type){  using boost::python::register_serialized;  register_serialized<packed_iarchive, packed_oarchive>(value, type);}} } } // end namespace boost::mpi::python#endif // BOOST_MPI_PYTHON_SERIALIZE_HPP

⌨️ 快捷键说明

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