⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oserializer.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
#ifndef BOOST_ARCHIVE_OSERIALIZER_HPP
#define BOOST_ARCHIVE_OSERIALIZER_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#pragma inline_depth(511)
#pragma inline_recursion(on)
#endif

#if defined(__MWERKS__)
#pragma inline_depth(511)
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// oserializer.hpp: interface for serialization system.

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.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)

//  See http://www.boost.org for updates, documentation, and revision history.

#include <cassert>

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_cast.hpp>
#include <boost/static_assert.hpp>
#include <boost/static_warning.hpp>

#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/serialization/is_abstract.hpp>

#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/greater_equal.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/not.hpp>

#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
    #include <boost/serialization/extended_type_info_typeid.hpp>
#endif

// the following is need only for dynamic cast of polymorphic pointers
#include <boost/archive/detail/basic_oarchive.hpp>
#include <boost/archive/detail/basic_oserializer.hpp>
#include <boost/archive/detail/archive_pointer_oserializer.hpp>

#include <boost/serialization/force_include.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/level.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/type_info_implementation.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/void_cast.hpp>

#include <boost/archive/archive_exception.hpp>

namespace boost {

namespace serialization {
    class extended_type_info;
} // namespace serialization

namespace archive {

// an accessor to permit friend access to archives.  Needed because
// some compilers don't handle friend templates completely
class save_access {
public:
    template<class Archive>
    static void end_preamble(Archive & ar){
        ar.end_preamble();
    }
    template<class Archive, class T>
    static void save_primitive(Archive & ar, const  T & t){
        ar.end_preamble();
        ar.save(t);
    }
};

namespace detail {

template<class Archive, class T>
class oserializer : public basic_oserializer
{
private:
    // private constructor to inhibit any existence other than the 
    // static one
    explicit oserializer() :
        basic_oserializer(
            * boost::serialization::type_info_implementation<T>::type::get_instance()
        )
    {}
public:
    virtual BOOST_DLLEXPORT void save_object_data(
        basic_oarchive & ar,    
        const void *x
    ) const BOOST_USED ;
    virtual bool class_info() const {
        return boost::serialization::implementation_level<T>::value 
            >= boost::serialization::object_class_info;
    }
    virtual bool tracking(const unsigned int flags) const {
//        if(0 != (flags &  no_tracking))
//            return false;
        return boost::serialization::tracking_level<T>::value == boost::serialization::track_always
            || boost::serialization::tracking_level<T>::value == boost::serialization::track_selectivly
            && serialized_as_pointer();
    }
    virtual unsigned int version() const {
        return ::boost::serialization::version<T>::value;
    }
    virtual bool is_polymorphic() const {
        typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<
            T
        >::type::is_polymorphic::type typex;
        return typex::value;
    }
    static oserializer & instantiate(){
        static oserializer instance;
        return instance;
    }
    virtual ~oserializer(){}
};

template<class Archive, class T>
BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
    basic_oarchive & ar,    
    const void *x
) const {
    // make sure call is routed through the highest interface that might
    // be specialized by the user.
    boost::serialization::serialize_adl(
        boost::smart_cast_reference<Archive &>(ar),
        * static_cast<T *>(const_cast<void *>(x)),
        version()
    );
}

// instantiation of this template creates a static object.  Note inversion of
// normal argument order to workaround bizarre error in MSVC 6.0 which only
// manifests iftself during compiler time.
template<class T, class Archive>
class pointer_oserializer : public archive_pointer_oserializer<Archive> 
{
private:
    virtual const basic_oserializer & get_basic_serializer() const {
        return oserializer<Archive, T>::instantiate();
    }
    virtual BOOST_DLLEXPORT void save_object_ptr(
        basic_oarchive & ar,
        const void * x
    ) const BOOST_USED ;
#if defined(__GNUC__) || ( defined(BOOST_MSVC) && (_MSC_VER <= 1300) )
public:
#endif
    // private constructor to inhibit any existence other than the 
    // static one.  Note GCC doesn't permit constructor to be private
    explicit BOOST_DLLEXPORT pointer_oserializer() BOOST_USED;
    static const pointer_oserializer instance;
public:
    #if !defined(__BORLANDC__)
    // at least one compiler (CW) seems to require that serialize_adl
    // be explicitly instantiated. Still under investigation. 
    void (* const m)(Archive &, T &, const unsigned);
    boost::serialization::extended_type_info * (* e)();
    #endif
    static BOOST_DLLEXPORT const pointer_oserializer & instantiate() BOOST_USED;
    virtual ~pointer_oserializer(){}
};

template<class T, class Archive>
BOOST_DLLEXPORT const pointer_oserializer<T, Archive> & 
pointer_oserializer<T, Archive>::instantiate(){
    return instance;
}

// note: instances of this template to be constructed before the main
// is called in order for things to be initialized properly.  For this
// reason, hiding the instance in a static function as was done above
// won't work here so we created a free instance here.
template<class T, class Archive>
const pointer_oserializer<T, Archive> pointer_oserializer<T, Archive>::instance;

template<class T, class Archive>
BOOST_DLLEXPORT void pointer_oserializer<T, Archive>::save_object_ptr(
    basic_oarchive & ar,
    const void * x
) const {
    assert(NULL != x);
    // make sure call is routed through the highest interface that might
    // be specialized by the user.
    T * t = static_cast<T *>(const_cast<void *>(x));
    const unsigned int file_version = boost::serialization::version<T>::value;
    Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
    boost::serialization::save_construct_data_adl<Archive, T>(
        ar_impl, 
        t, 
        file_version
    );
    ar_impl << boost::serialization::make_nvp(NULL, * t);
}

template<class T, class Archive>
#if !defined(__BORLANDC__)
BOOST_DLLEXPORT pointer_oserializer<T, Archive>::pointer_oserializer() :
    archive_pointer_oserializer<Archive>(
        * boost::serialization::type_info_implementation<T>::type::get_instance()
    ),
    m(boost::serialization::serialize_adl<Archive, T>),
    e(boost::serialization::type_info_implementation<T>::type::get_instance)
#else
BOOST_DLLEXPORT pointer_oserializer<T, Archive>::pointer_oserializer() :
    archive_pointer_oserializer<Archive>(
        * boost::serialization::type_info_implementation<T>::type::get_instance()
    )
#endif
{
    // make sure appropriate member function is instantiated
    oserializer<Archive, T> & bos = oserializer<Archive, T>::instantiate();
    bos.set_bpos(this);
}

template<class Archive, class T>
struct save_non_pointer_type {
    // note this bounces the call right back to the archive
    // with no runtime overhead
    struct save_primitive {
        static void invoke(Archive & ar, const T & t){
            save_access::save_primitive(ar, t);
        }
    };
    // same as above but passes through serialization
    struct save_only {
        static void invoke(Archive & ar, const T & t){
            // make sure call is routed through the highest interface that might
            // be specialized by the user.
            boost::serialization::serialize_adl(
                ar, 
                const_cast<T &>(t), 
                ::boost::serialization::version<T>::value
            );
        }
    };
    // adds class information to the archive. This includes
    // serialization level and class version
    struct save_standard {
        static void invoke(Archive &ar, const T & t){
            ar.save_object(& t, oserializer<Archive, T>::instantiate());
        }
    };

    // adds class information to the archive. This includes
    // serialization level and class version
    struct save_conditional {
        static void invoke(Archive &ar, const T &t){
            //if(0 == (ar.get_flags() & no_tracking))
                save_standard::invoke(ar, t);
            //else
            //   save_only::invoke(ar, t);
        }
    };

    typedef 
        BOOST_DEDUCED_TYPENAME mpl::eval_if<
        // if its primitive
            mpl::equal_to<
                boost::serialization::implementation_level<T>,
                mpl::int_<boost::serialization::primitive_type>
            >,
            mpl::identity<save_primitive>,
        // else
        BOOST_DEDUCED_TYPENAME mpl::eval_if<

⌨️ 快捷键说明

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