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

📄 iserializer.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
        // this addresses an obscure situtation that occurs when 
        // load_constructor de-serializes something through a pointer.
        ar.next_object_pointer(t);
        boost::serialization::load_construct_data_adl<Archive, T>(
            ar_impl,
            t, 
            file_version
        );
    }
    BOOST_CATCH(...){
        BOOST_RETHROW;
    }
    BOOST_CATCH_END

    ar_impl >> boost::serialization::make_nvp(NULL, * t);
    ap.release();
}

template<class T, class Archive>
#if !defined(__BORLANDC__)
BOOST_DLLEXPORT pointer_iserializer<T, Archive>::pointer_iserializer() :
    archive_pointer_iserializer<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_iserializer<T, Archive>::pointer_iserializer() :
    archive_pointer_iserializer<Archive>(
        * boost::serialization::type_info_implementation<T>::type::get_instance()
    )
#endif
{
    iserializer<Archive, T> & bis = iserializer<Archive, T>::instantiate();
    bis.set_bpis(this);
}

template<class Archive, class T>
struct load_non_pointer_type {
    // note this bounces the call right back to the archive
    // with no runtime overhead
    struct load_primitive {
        static void invoke(Archive & ar, T & t){
            load_access::load_primitive(ar, t);
        }
    };
    // note this bounces the call right back to the archive
    // with no runtime overhead
    struct load_only {
        static void invoke(Archive & ar, T & t){
            // short cut to user's serializer
            // make sure call is routed through the higest interface that might
            // be specialized by the user.
            boost::serialization::serialize_adl(
                ar, t, boost::serialization::version<T>::value
            );
        }
    };

    // note this save class information including version
    // and serialization level to the archive
    struct load_standard {
        static void invoke(Archive &ar, T &t){
            //BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
            // borland - for some reason T is const here - even though
            // its not called that way - so fix it her
            typedef BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type typex;
            void * x = & const_cast<typex &>(t);
            ar.load_object(x, iserializer<Archive, T>::instantiate());
        }
    };

    struct load_conditional {
        static void invoke(Archive &ar, T &t){
            //if(0 == (ar.get_flags() & no_tracking))
                load_standard::invoke(ar, t);
            //else
            //    load_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<load_primitive>,
        // else
        BOOST_DEDUCED_TYPENAME mpl::eval_if<
        // class info / version
        mpl::greater_equal<
                    boost::serialization::implementation_level<T>,
                    mpl::int_<boost::serialization::object_class_info>
                >,
        // do standard load
        mpl::identity<load_standard>,
    // else
    BOOST_DEDUCED_TYPENAME mpl::eval_if<
        // no tracking
                mpl::equal_to<
                    boost::serialization::tracking_level<T>,
                    mpl::int_<boost::serialization::track_never>
            >,
            // do a fast load
            mpl::identity<load_only>,
        // else
        // do a fast load only tracking is turned off
        mpl::identity<load_conditional>
    > > >::type typex;

    static void invoke(Archive & ar, T &t){
        BOOST_STATIC_ASSERT((
            mpl::greater_equal<
                boost::serialization::implementation_level<T>, 
                mpl::int_<boost::serialization::primitive_type>
            >::value
        ));
        typex::invoke(ar, t);
    }
};

template<class Archive, class Tptr>
struct load_pointer_type {
    template<class T>
    struct abstract
    {
        static const basic_pointer_iserializer * register_type(Archive & /* ar */){
            #if ! defined(__BORLANDC__)
            typedef BOOST_DEDUCED_TYPENAME 
                boost::serialization::type_info_implementation<T>::type::is_polymorphic typex;
            // it has? to be polymorphic
            BOOST_STATIC_ASSERT(typex::value);
            #endif
            return static_cast<basic_pointer_iserializer *>(NULL);
         }
    };

    template<class T>
    struct non_abstract
    {
        static const basic_pointer_iserializer * register_type(Archive & ar){
            return ar.register_type(static_cast<T *>(NULL));
        }
    };

    template<class T>
    static const basic_pointer_iserializer * register_type(Archive &ar, T & /*t*/){
        // there should never be any need to load an abstract polymorphic 
        // class pointer.  Inhibiting code generation for this
        // permits abstract base classes to be used - note: exception
        // virtual serialize functions used for plug-ins
        typedef BOOST_DEDUCED_TYPENAME
            mpl::eval_if<
                serialization::is_abstract<T>,
                mpl::identity<abstract<T> >,
                mpl::identity<non_abstract<T> >    
            >::type typex;
        return typex::register_type(ar);
    }

    template<class T>
    static T * pointer_tweak(
        const boost::serialization::extended_type_info & eti,
        void * t,
        T &
    ) {
        // tweak the pointer back to the base class
        return static_cast<T *>(
            boost::serialization::void_upcast(
                eti,
                * boost::serialization::type_info_implementation<T>::type::get_instance(),
                t
            )
        );
    }

    static void invoke(Archive & ar, Tptr & t){
        const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t);
        const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer(
            * reinterpret_cast<void **>(&t),
            bpis_ptr,
            archive_pointer_iserializer<Archive>::find
        );
        // if the pointer isn't that of the base class
        if(newbpis_ptr != bpis_ptr){
            t = pointer_tweak(newbpis_ptr->get_eti(), t, *t);
        }
    }
};

template<class Archive, class T>
struct load_enum_type {
    static void invoke(Archive &ar, T &t){
        // convert integers to correct enum to load
        int i;
        ar >> boost::serialization::make_nvp(NULL, i);
        t = static_cast<T>(i);
    }
};

template<class Archive, class T>
struct load_array_type {
    static void invoke(Archive &ar, T &t){
        // convert integers to correct enum to load
        int current_count = sizeof(t) / (
            static_cast<char *>(static_cast<void *>(&t[1])) 
            - static_cast<char *>(static_cast<void *>(&t[0]))
        );
        int count;
        ar >> BOOST_SERIALIZATION_NVP(count);
        if(count > current_count)
            boost::throw_exception(archive::archive_exception(
                boost::archive::archive_exception::array_size_too_short
            ));
        int i;
        for(i = 0; i < count; ++i)
            ar >> boost::serialization::make_nvp("item", t[i]);
    }
};

// note bogus arguments to workaround msvc 6 silent runtime failure
template<class Archive, class T>
BOOST_DLLEXPORT 
inline const basic_pointer_iserializer &
instantiate_pointer_iserializer(
    Archive * /* ar = NULL */,
    T * /* t = NULL */
) BOOST_USED;

template<class Archive, class T>
BOOST_DLLEXPORT 
inline const basic_pointer_iserializer &
instantiate_pointer_iserializer(
    Archive * /* ar = NULL */,
    T * /* t = NULL */
){
    // note: reversal of order of arguments to work around msvc 6.0 bug
    // that manifests itself while trying to link.
    return pointer_iserializer<T, Archive>::instantiate();
}

} // detail

template<class Archive, class T>
inline void load(Archive &ar, T &t){
    // if this assertion trips. It means we're trying to load a
    // const object with a compiler that doesn't have correct
    // funtion template ordering.  On other compilers, this is
    // handled below.
    BOOST_STATIC_ASSERT(! boost::is_const<T>::value);
    typedef
        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer<T>,
            mpl::identity<detail::load_pointer_type<Archive, T> >
        ,//else
        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>,
            mpl::identity<detail::load_array_type<Archive, T> >
        ,//else
        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum<T>,
            mpl::identity<detail::load_enum_type<Archive, T> >
        ,//else
            mpl::identity<detail::load_non_pointer_type<Archive, T> >
        >
        >
        >::type typex;
    typex::invoke(ar, t);
}

// BORLAND
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x560))
// borland has a couple fo problems
// a) if function is partiall specialized - see below
// const paramters are transformed to non-const ones
// b) implementation of base_object can't be made to work
// correctly which results in all base_object s being const.
// So, strip off the const for borland.  This breaks the trap
// for loading const objects - but I see no alternative
template<class Archive, class T>
inline void load(Archive &ar, const T & t){
        load(ar, const_cast<T &>(t));
}
#endif

// let wrappers through.  (Someday implement is_wrapper)
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
template<class Archive, class T>
inline void load(Archive &ar, const serialization::nvp<T> &t){
        boost::archive::load(ar, const_cast<serialization::nvp<T> &>(t));
}
template<class Archive>
inline void load(Archive &ar, const serialization::binary_object &t){
        boost::archive::load(ar, const_cast<serialization::binary_object &>(t));
}

//template<class Archive, class T>
//inline void load(Archive &ar, const serialization::binary_object &t){
//      load(ar, const_cast<binary_object &>(t));
//}
#endif

} // namespace archive
} // namespace boost

#endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP

⌨️ 快捷键说明

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