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