📄 oserializer.hpp
字号:
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< mpl::and_< // no class info / version mpl::less< boost::serialization::implementation_level<T>, mpl::int_<boost::serialization::object_class_info> >, // and no tracking mpl::equal_to< boost::serialization::tracking_level<T>, mpl::int_<boost::serialization::track_never> > >, // do a fast save mpl::identity<save_only>, // else // do standard save mpl::identity<save> > >::type typex; // note: the invokeX keeps borland from getting confused typex::invokex(ar, t); #endif }};template<class Archive, class TPtr>struct save_pointer_type { template<class T> struct abstract { static const basic_pointer_oserializer * register_type(Archive & /* ar */){ typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<T>::type::is_polymorphic typex; // it has? to be polymorphic BOOST_STATIC_ASSERT(typex::value); return static_cast<const basic_pointer_oserializer *>(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 remove_const<T>::type type; typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< is_abstract<T>, mpl::identity<abstract<type> >, mpl::identity<non_abstract<type> > >::type typex; return typex::register_type(ar); } template<class T> struct non_polymorphic { static void save( Archive &ar, const T & t, const basic_pointer_oserializer * bpos_ptr ){ // save the requested pointer type ar.save_pointer(& t, bpos_ptr); } }; template<class T> struct polymorphic { static void save( Archive &ar, const T & t, const basic_pointer_oserializer * bpos_ptr ){ // currently only known to work with VC #if defined(BOOST_MSVC) // note: if you program traps here its because // a) your serializing through a baae class pointer // b) to an archive not in the known list. // This will usually occur when one makes a custom archive and // forgets to add it to the list of known archive. If the derived // class is explictly registered or if no derived pointer is used // there won't be a problem - that's why its a warning. However // if you export the derived type and the archive used isn't on the // known list it will fail below at execution time and one will have // a hell of time figuring out why. Hence this warning. BOOST_STATIC_WARNING(( mpl::not_< mpl::and_< mpl::not_<mpl::empty<known_archive_types<0>::type > >, is_same< mpl::end<known_archive_types<false>::type >::type, BOOST_DEDUCED_TYPENAME mpl::find<known_archive_types<false>::type, Archive>::type > > > ::value )); #endif const boost::serialization::extended_type_info * this_type = boost::serialization::type_info_implementation<T>::type::get_instance(); // 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 = boost::serialization::type_info_implementation<T>::type::get_derived_extended_type_info(t); // note:if this exception is thrown, be sure that derived pointer // is either regsitered or exported. if(NULL == true_type){ boost::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){ ar.save_pointer(vp, bpos_ptr); 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, &t); if(NULL == vp){ boost::throw_exception( archive_exception(archive_exception::unregistered_cast) ); } // sice true_type is valid, and this only gets made if the // pointer oserializer object has been created, this should never // fail bpos_ptr = archive_pointer_oserializer<Archive>::find(* true_type); assert(NULL != bpos_ptr); if(NULL == bpos_ptr) boost::throw_exception( archive_exception(archive_exception::unregistered_class) ); ar.save_pointer(vp, bpos_ptr); } }; template<class T> static void save( Archive & ar, const T &t, const basic_pointer_oserializer * bpos_ptr ){ typedef BOOST_DEDUCED_TYPENAME remove_const<T>::type typex; typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< BOOST_DEDUCED_TYPENAME boost::serialization:: type_info_implementation<T>::type::is_polymorphic, mpl::identity<polymorphic<typex> >, mpl::identity<non_polymorphic<typex> > >::type typey; typey::save(ar, const_cast<typex &>(t), bpos_ptr); } 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 const basic_pointer_oserializer * bpos_ptr = register_type(ar, * t); if(NULL == t){ basic_oarchive & boa = boost::smart_cast_reference<basic_oarchive &>(ar); boa.save_null_pointer(); save_access::end_preamble(ar); return; } save(ar, * t, bpos_ptr); };};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){ 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); 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// declaration to satisfy gcctemplate<class Archive, class T>BOOST_DLLEXPORT inline const basic_pointer_oserializer &instantiate_pointer_oserializer( Archive * /* ar = NULL */, T * /* t = NULL */) BOOST_USED ;// definitiontemplate<class Archive, class T>BOOST_DLLEXPORT inline const basic_pointer_oserializer &instantiate_pointer_oserializer( 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_oserializer<T, Archive>::instance;}} // 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);}} // namespace archive} // namespace boost#endif // BOOST_ARCHIVE_OSERIALIZER_HPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -