1 #ifndef BOOST_ARCHIVE_OSERIALIZER_HPP
2 #define BOOST_ARCHIVE_OSERIALIZER_HPP
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 # pragma inline_depth(511)
8 # pragma inline_recursion(on)
11 #if defined(__MWERKS__)
12 # pragma inline_depth(511)
25 #include <boost/config.hpp>
26 #include <boost/detail/workaround.hpp>
27 #include <boost/mpl/and.hpp>
28 #include <boost/mpl/empty.hpp>
29 #include <boost/mpl/equal_to.hpp>
30 #include <boost/mpl/eval_if.hpp>
31 #include <boost/mpl/greater_equal.hpp>
32 #include <boost/mpl/identity.hpp>
33 #include <boost/mpl/int.hpp>
34 #include <boost/mpl/less.hpp>
35 #include <boost/mpl/list.hpp>
36 #include <boost/mpl/not.hpp>
37 #include <boost/serialization/is_abstract.hpp>
38 #include <boost/smart_cast.hpp>
39 #include <boost/static_assert.hpp>
40 #include <boost/static_warning.hpp>
41 #include <boost/throw_exception.hpp>
42 #include <boost/type_traits/is_const.hpp>
43 #include <boost/type_traits/is_enum.hpp>
44 #include <boost/type_traits/is_fundamental.hpp>
45 #include <boost/type_traits/is_pointer.hpp>
46 #include <boost/type_traits/is_same.hpp>
47 #include <boost/type_traits/is_volatile.hpp>
51 #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
52 # include <boost/serialization/extended_type_info_typeid.hpp>
55 #include <boost/archive/archive_exception.hpp>
56 #include <boost/archive/detail/archive_pointer_oserializer.hpp>
57 #include <boost/archive/detail/basic_oarchive.hpp>
58 #include <boost/archive/detail/basic_oserializer.hpp>
59 #include <boost/serialization/force_include.hpp>
60 #include <boost/serialization/level.hpp>
61 #include <boost/serialization/nvp.hpp>
62 #include <boost/serialization/serialization.hpp>
63 #include <boost/serialization/tracking.hpp>
64 #include <boost/serialization/type_info_implementation.hpp>
65 #include <boost/serialization/version.hpp>
66 #include <boost/serialization/void_cast.hpp>
71 namespace serialization
73 class extended_type_info;
84 template<
class Archive>
89 template<
class Archive,
class T>
100 template<
class Archive,
class T>
106 explicit oserializer() : basic_oserializer(*boost::serialization::type_info_implementation<T>::type::get_instance())
111 virtual BOOST_DLLEXPORT
void save_object_data(basic_oarchive & ar,
const void * x)
const BOOST_USED;
114 return boost::serialization::implementation_level<T>::value >= boost::serialization::object_class_info;
120 return boost::serialization::tracking_level<T>::value == boost::serialization::track_always
121 || boost::serialization::tracking_level<T>::value == boost::serialization::track_selectivly
122 && serialized_as_pointer();
126 return ::boost::serialization::version<T>::value;
130 typedef BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<T>::type::is_polymorphic::type typex;
141 template<
class Archive,
class T>
146 boost::serialization::serialize_adl(boost::smart_cast_reference<Archive &>(ar),
147 *
static_cast<T *
>(
const_cast<void *
>(x)), version());
153 template<
class T,
class Archive>
157 virtual const basic_oserializer & get_basic_serializer()
const
161 virtual BOOST_DLLEXPORT
void save_object_ptr(basic_oarchive & ar,
const void * x)
const BOOST_USED;
162 #if defined(__GNUC__) || (defined(BOOST_MSVC) && (_MSC_VER <= 1300))
171 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
174 void (*
const m)(Archive &, T &,
const unsigned);
175 boost::serialization::extended_type_info * (*e)();
181 template<
class T,
class Archive>
191 template<
class T,
class Archive>
194 template<
class T,
class Archive>
200 T * t =
static_cast<T *
>(
const_cast<void *
>(x));
201 const unsigned int file_version = boost::serialization::version<T>::value;
202 Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar);
203 boost::serialization::save_construct_data_adl<Archive, T>(ar_impl, t, file_version);
204 ar_impl << boost::serialization::make_nvp(NULL, *t);
207 template<
class T,
class Archive>
208 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
209 BOOST_DLLEXPORT pointer_oserializer<T, Archive>::pointer_oserializer()
210 : archive_pointer_oserializer<Archive>(*
boost::serialization::type_info_implementation<T>::type::get_instance()),
211 m(
boost::serialization::serialize_adl<Archive, T>),
212 e(
boost::serialization::type_info_implementation<T>::type::get_instance)
214 BOOST_DLLEXPORT pointer_oserializer<T, Archive>::pointer_oserializer()
215 : archive_pointer_oserializer<Archive>(*
boost::serialization::type_info_implementation<T>::type::get_instance())
223 template<
class Archive,
class T>
230 static void invoke(Archive & ar,
const T & t)
238 static void invoke(Archive & ar,
const T & t)
242 boost::serialization::serialize_adl(ar,
const_cast<T &
>(t), ::boost::serialization::version<T>::value);
249 static void invoke(Archive & ar,
const T & t)
259 static void invoke(Archive & ar,
const T & t)
268 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
270 mpl::equal_to<boost::serialization::implementation_level<T>, mpl::int_<boost::serialization::primitive_type>>,
271 mpl::identity<save_primitive>,
273 BOOST_DEDUCED_TYPENAME mpl::eval_if<
275 mpl::greater_equal<boost::serialization::implementation_level<T>,
276 mpl::int_<boost::serialization::object_class_info>>,
278 mpl::identity<save_standard>,
280 BOOST_DEDUCED_TYPENAME mpl::eval_if<
282 mpl::equal_to<boost::serialization::tracking_level<T>, mpl::int_<boost::serialization::track_never>>,
284 mpl::identity<save_only>,
287 mpl::identity<save_conditional>>>>::type
typex;
289 static void invoke(Archive & ar,
const T & t)
296 BOOST_STATIC_ASSERT((mpl::greater_equal<boost::serialization::implementation_level<T>,
297 mpl::int_<boost::serialization::primitive_type>>::value));
298 typex::invoke(ar, t);
302 template<
class Archive,
class TPtr>
311 BOOST_STATIC_ASSERT(boost::serialization::type_info_implementation<T>::type::is_polymorphic::value);
312 return static_cast<const basic_pointer_oserializer *
>(NULL);
321 return ar.register_type(
static_cast<T *
>(NULL));
332 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<serialization::is_abstract<T>, mpl::identity<abstract<T>>,
333 mpl::identity<non_abstract<T>>>::type typex;
334 return typex::register_type(ar);
340 static void save(Archive & ar,
const T & t,
const basic_pointer_oserializer * bpos_ptr)
343 ar.save_pointer(&t, bpos_ptr);
350 static void save(Archive & ar,
const T & t,
const basic_pointer_oserializer * bpos_ptr)
352 const boost::serialization::extended_type_info * this_type =
353 boost::serialization::type_info_implementation<T>::type::get_instance();
356 assert(NULL != this_type);
357 const boost::serialization::extended_type_info * true_type =
358 boost::serialization::type_info_implementation<T>::type::get_derived_extended_type_info(t);
361 if(NULL == true_type)
363 boost::throw_exception(archive_exception(archive_exception::unregistered_class));
367 const void * vp =
static_cast<const void *
>(&t);
368 if(*this_type == *true_type)
370 ar.save_pointer(vp, bpos_ptr);
375 vp = serialization::void_downcast(*true_type, *this_type, &t);
378 boost::throw_exception(archive_exception(archive_exception::unregistered_cast));
384 bpos_ptr = archive_pointer_oserializer<Archive>::find(*true_type);
385 assert(NULL != bpos_ptr);
386 if(NULL == bpos_ptr) boost::throw_exception(archive_exception(archive_exception::unregistered_class));
387 ar.save_pointer(vp, bpos_ptr);
392 static void save(Archive & ar,
const T & t,
const basic_pointer_oserializer * bpos_ptr)
394 typedef BOOST_DEDUCED_TYPENAME
395 mpl::eval_if<BOOST_DEDUCED_TYPENAME boost::serialization::type_info_implementation<T>::type::is_polymorphic,
396 mpl::identity<polymorphic<T>>, mpl::identity<non_polymorphic<T>>>::type typey;
403 BOOST_STATIC_ASSERT(!boost::is_const<T>::value);
406 static void invoke(Archive & ar,
const TPtr t)
408 #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
420 const basic_pointer_oserializer * bpos_ptr =
register_type(ar, *t);
423 basic_oarchive & boa = boost::smart_cast_reference<basic_oarchive &>(ar);
424 boa.save_null_pointer();
428 save(ar, *t, bpos_ptr);
432 template<
class Archive,
class T>
435 static void invoke(Archive & ar,
const T & t)
438 const int i =
static_cast<int>(t);
439 ar << boost::serialization::make_nvp(NULL, i);
443 template<
class Archive,
class T>
446 static void invoke(Archive & ar,
const T & t)
450 int count =
sizeof(t)
451 / (
static_cast<const char *
>(
static_cast<const void *
>(&t[1]))
452 -
static_cast<const char *
>(
static_cast<const void *
>(&t[0])));
453 ar << BOOST_SERIALIZATION_NVP(count);
455 for(i = 0; i < count; ++i) ar << boost::serialization::make_nvp(
"item", t[i]);
461 template<
class Archive,
class T>
466 template<
class Archive,
class T>
478 template<
class Archive,
class T>
479 inline void save(Archive & ar,
const T & t)
481 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
482 is_pointer<T>, mpl::identity<detail::save_pointer_type<Archive, T>>,
484 BOOST_DEDUCED_TYPENAME mpl::eval_if<
485 is_enum<T>, mpl::identity<detail::save_enum_type<Archive, T>>,
487 BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array<T>, mpl::identity<detail::save_array_type<Archive, T>>,
489 mpl::identity<detail::save_non_pointer_type<Archive, T>>>>>::type typex;
490 typex::invoke(ar, t);
493 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
498 typedef BOOST_DEDUCED_TYPENAME mpl::if_<
500 BOOST_DEDUCED_TYPENAME mpl::equal_to<serialization::tracking_level<T>, mpl::int_<serialization::track_never>>,
502 mpl::not_<is_pointer<T>>,
510 template<
class Archive,
class T>
511 inline void save(Archive & ar, T & t)
520 save(ar,
const_cast<const T &
>(t));
527 #endif // BOOST_ARCHIVE_OSERIALIZER_HPP