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 + -
显示快捷键?