📄 iserializer.hpp
字号:
// 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 + -