oserializer.hpp

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

HPP
547
字号
            // do a fast save            mpl::identity<save_only>,        // else            // do a fast save only tracking is turned off            mpl::identity<save_conditional>        > > >::type typex;     static void invoke(Archive & ar, const T & t){        // check that we're not trying to serialize something that        // has been marked not to be serialized.  If this your program        // traps here, you've tried to serialize a class whose trait        // has been marked "non-serializable". Either reset the trait        // (see level.hpp) or change program not to serialize items of this class        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 save_pointer_type {    template<class T>    struct abstract    {        static const basic_pointer_oserializer * register_type(Archive & /* ar */){            // it has? to be polymorphic            BOOST_STATIC_ASSERT(boost::is_polymorphic<T>::value);            return NULL;        }    };    template<class T>    struct non_abstract    {        static const basic_pointer_oserializer * register_type(Archive & ar){            return ar.register_type(static_cast<T *>(NULL));        }    };    template<class T>    static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){        // there should never be any need to save 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<                boost::serialization::is_abstract<T>,                mpl::identity<abstract<T> >,                mpl::identity<non_abstract<T> >                   >::type typex;        return typex::register_type(ar);    }    template<class T>    struct non_polymorphic    {        static void save(            Archive &ar,             T & t        ){            const basic_pointer_oserializer & bpos =                 boost::serialization::singleton<                    pointer_oserializer<Archive, T>                >::get_const_instance();            // save the requested pointer type            ar.save_pointer(& t, & bpos);        }    };    template<class T>    struct polymorphic    {        static void save(            Archive &ar,             T & t        ){            BOOST_DEDUCED_TYPENAME             boost::serialization::type_info_implementation<T>::type const            & i = boost::serialization::type_info_implementation<T>::type                    ::get_const_instance();            boost::serialization::extended_type_info const * const this_type = & i;            // retrieve the true type of the object pointed to            // if this assertion fails its an error in this library            assert(NULL != this_type);            const boost::serialization::extended_type_info * true_type =                i.get_derived_extended_type_info(t);            // note:if this exception is thrown, be sure that derived pointer            // is either registered or exported.            if(NULL == true_type){                boost::serialization::throw_exception(                    archive_exception(archive_exception::unregistered_class)                );            }            // if its not a pointer to a more derived type            const void *vp = static_cast<const void *>(&t);            if(*this_type == *true_type){                const basic_pointer_oserializer * bpos = register_type(ar, t);                ar.save_pointer(vp, bpos);                return;            }            // convert pointer to more derived type. if this is thrown            // it means that the base/derived relationship hasn't be registered            vp = serialization::void_downcast(                *true_type,                 *this_type,                 static_cast<const void *>(&t)            );            if(NULL == vp){                boost::serialization::throw_exception(                    archive_exception(archive_exception::unregistered_cast)                );            }            // since true_type is valid, and this only gets made if the             // pointer oserializer object has been created, this should never            // fail            const basic_pointer_oserializer * bpos                 = archive_pointer_oserializer<Archive>::find(* true_type);            assert(NULL != bpos);            if(NULL == bpos)                boost::serialization::throw_exception(                    archive_exception(archive_exception::unregistered_class)                );            ar.save_pointer(vp, bpos);        }    };    // out of line selector works around borland quirk    template<class T>    struct conditional {        typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<            is_polymorphic<T>,            mpl::identity<polymorphic<T> >,            mpl::identity<non_polymorphic<T> >        >::type type;    };    // used to convert TPtr in to a pointer to a T    template<class T>    static void save(        Archive & ar,         const T & t    ){        conditional<T>::type::save(ar, const_cast<T &>(t));    }    template<class T>    static void const_check(T & t){        BOOST_STATIC_ASSERT(! boost::is_const<T>::value);    }    static void invoke(Archive &ar, const TPtr t){        #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION            // if your program traps here, its because you tried to do            // something like ar << t where t is a pointer to a const value            // void f3(A const* a, text_oarchive& oa)            // {            //     oa << a;            // }            // with a compiler which doesn't support remove_const            // const_check(* t);        #else            // otherwise remove the const        #endif        register_type(ar, * t);        if(NULL == t){            basic_oarchive & boa                 = boost::serialization::smart_cast_reference<basic_oarchive &>(ar);            boa.save_null_pointer();            save_access::end_preamble(ar);            return;        }        save(ar, * t);    };};template<class Archive, class T>struct save_enum_type{    static void invoke(Archive &ar, const T &t){        // convert enum to integers on save        const int i = static_cast<int>(t);        ar << boost::serialization::make_nvp(NULL, i);    }};template<class Archive, class T>struct save_array_type{    static void invoke(Archive &ar, const T &t){        typedef BOOST_DEDUCED_TYPENAME boost::remove_extent<T>::type value_type;                save_access::end_preamble(ar);        // consider alignment        int count = sizeof(t) / (            static_cast<const char *>(static_cast<const void *>(&t[1]))             - static_cast<const char *>(static_cast<const void *>(&t[0]))        );        ar << BOOST_SERIALIZATION_NVP(count);        ar << serialization::make_array(static_cast<value_type const*>(&t[0]),count);    }};} // detailtemplate<class Archive, class T>inline void save(Archive & ar, const T &t){    typedef         BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer<T>,            mpl::identity<detail::save_pointer_type<Archive, T> >,        //else        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum<T>,            mpl::identity<detail::save_enum_type<Archive, T> >,        //else        BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>,            mpl::identity<detail::save_array_type<Archive, T> >,        //else            mpl::identity<detail::save_non_pointer_type<Archive, T> >        >        >        >::type typex;    typex::invoke(ar, t);}#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERINGtemplate<class T>struct check_tracking {    typedef BOOST_DEDUCED_TYPENAME mpl::if_<        // if its never tracked.        BOOST_DEDUCED_TYPENAME mpl::equal_to<            serialization::tracking_level<T>,            mpl::int_<serialization::track_never>        >,        // it better not be a pointer        mpl::not_<is_pointer<T> >,    //else        // otherwise if it might be tracked.  So there shouldn't        // be any problem making a const        is_const<T>    >::type typex;    BOOST_STATIC_CONSTANT(bool, value = typex::value);};template<class Archive, class T>inline void save(Archive & ar, T &t){    // if your program traps here, it indicates that your doing one of the following:    // a) serializing an object of a type marked "track_never" through a pointer.    // b) saving an non-const object of a type not markd "track_never)    // Either of these conditions may be an indicator of an error usage of the    // serialization library and should be double checked.  See documentation on    // object tracking.  Also, see the "rationale" section of the documenation    // for motivation for this checking.    BOOST_STATIC_WARNING(check_tracking<T>::value);        save(ar, const_cast<const T &>(t));}#endif} // namespace archive} // namespace boost#endif // BOOST_ARCHIVE_OSERIALIZER_HPP

⌨️ 快捷键说明

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