annotate DEPENDENCIES/generic/include/boost/archive/detail/oserializer.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 #ifndef BOOST_ARCHIVE_OSERIALIZER_HPP
Chris@16 2 #define BOOST_ARCHIVE_OSERIALIZER_HPP
Chris@16 3
Chris@16 4 // MS compatible compilers support #pragma once
Chris@101 5 #if defined(_MSC_VER)
Chris@16 6 # pragma once
Chris@16 7 #pragma inline_depth(511)
Chris@16 8 #pragma inline_recursion(on)
Chris@16 9 #endif
Chris@16 10
Chris@16 11 #if defined(__MWERKS__)
Chris@16 12 #pragma inline_depth(511)
Chris@16 13 #endif
Chris@16 14
Chris@16 15 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
Chris@16 16 // oserializer.hpp: interface for serialization system.
Chris@16 17
Chris@16 18 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
Chris@16 19 // Use, modification and distribution is subject to the Boost Software
Chris@16 20 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 21 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 22
Chris@16 23 // See http://www.boost.org for updates, documentation, and revision history.
Chris@16 24
Chris@16 25 #include <boost/assert.hpp>
Chris@16 26 #include <cstddef> // NULL
Chris@16 27
Chris@16 28 #include <boost/config.hpp>
Chris@16 29 #include <boost/static_assert.hpp>
Chris@16 30 #include <boost/detail/workaround.hpp>
Chris@16 31
Chris@16 32 #include <boost/mpl/eval_if.hpp>
Chris@16 33 #include <boost/mpl/equal_to.hpp>
Chris@16 34 #include <boost/mpl/greater_equal.hpp>
Chris@16 35 #include <boost/mpl/identity.hpp>
Chris@16 36
Chris@16 37 #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO
Chris@16 38 #include <boost/serialization/extended_type_info_typeid.hpp>
Chris@16 39 #endif
Chris@16 40 #include <boost/serialization/throw_exception.hpp>
Chris@16 41 #include <boost/serialization/smart_cast.hpp>
Chris@16 42 #include <boost/serialization/assume_abstract.hpp>
Chris@16 43 #include <boost/serialization/static_warning.hpp>
Chris@16 44
Chris@16 45 #include <boost/type_traits/is_pointer.hpp>
Chris@16 46 #include <boost/type_traits/is_enum.hpp>
Chris@16 47 #include <boost/type_traits/is_const.hpp>
Chris@16 48 #include <boost/type_traits/is_polymorphic.hpp>
Chris@16 49 #include <boost/type_traits/remove_extent.hpp>
Chris@16 50
Chris@16 51 #include <boost/serialization/serialization.hpp>
Chris@16 52 #include <boost/serialization/version.hpp>
Chris@16 53 #include <boost/serialization/level.hpp>
Chris@16 54 #include <boost/serialization/tracking.hpp>
Chris@16 55 #include <boost/serialization/type_info_implementation.hpp>
Chris@16 56 #include <boost/serialization/nvp.hpp>
Chris@16 57 #include <boost/serialization/void_cast.hpp>
Chris@16 58 #include <boost/serialization/array.hpp>
Chris@16 59 #include <boost/serialization/collection_size_type.hpp>
Chris@16 60 #include <boost/serialization/singleton.hpp>
Chris@16 61
Chris@16 62 #include <boost/archive/archive_exception.hpp>
Chris@16 63 #include <boost/archive/detail/basic_oarchive.hpp>
Chris@16 64 #include <boost/archive/detail/basic_oserializer.hpp>
Chris@16 65 #include <boost/archive/detail/basic_pointer_oserializer.hpp>
Chris@16 66 #include <boost/archive/detail/archive_serializer_map.hpp>
Chris@16 67 #include <boost/archive/detail/check.hpp>
Chris@16 68
Chris@16 69 namespace boost {
Chris@16 70
Chris@16 71 namespace serialization {
Chris@16 72 class extended_type_info;
Chris@16 73 } // namespace serialization
Chris@16 74
Chris@16 75 namespace archive {
Chris@16 76
Chris@16 77 // an accessor to permit friend access to archives. Needed because
Chris@16 78 // some compilers don't handle friend templates completely
Chris@16 79 class save_access {
Chris@16 80 public:
Chris@16 81 template<class Archive>
Chris@16 82 static void end_preamble(Archive & ar){
Chris@16 83 ar.end_preamble();
Chris@16 84 }
Chris@16 85 template<class Archive, class T>
Chris@16 86 static void save_primitive(Archive & ar, const T & t){
Chris@16 87 ar.end_preamble();
Chris@16 88 ar.save(t);
Chris@16 89 }
Chris@16 90 };
Chris@16 91
Chris@16 92 namespace detail {
Chris@16 93
Chris@16 94 #ifdef BOOST_MSVC
Chris@16 95 # pragma warning(push)
Chris@16 96 # pragma warning(disable : 4511 4512)
Chris@16 97 #endif
Chris@16 98
Chris@16 99 template<class Archive, class T>
Chris@16 100 class oserializer : public basic_oserializer
Chris@16 101 {
Chris@16 102 private:
Chris@16 103 // private constructor to inhibit any existence other than the
Chris@16 104 // static one
Chris@16 105 public:
Chris@16 106 explicit BOOST_DLLEXPORT oserializer() :
Chris@16 107 basic_oserializer(
Chris@16 108 boost::serialization::singleton<
Chris@101 109 typename
Chris@16 110 boost::serialization::type_info_implementation< T >::type
Chris@16 111 >::get_const_instance()
Chris@16 112 )
Chris@16 113 {}
Chris@16 114 virtual BOOST_DLLEXPORT void save_object_data(
Chris@16 115 basic_oarchive & ar,
Chris@16 116 const void *x
Chris@16 117 ) const BOOST_USED;
Chris@16 118 virtual bool class_info() const {
Chris@16 119 return boost::serialization::implementation_level< T >::value
Chris@16 120 >= boost::serialization::object_class_info;
Chris@16 121 }
Chris@16 122 virtual bool tracking(const unsigned int /* flags */) const {
Chris@16 123 return boost::serialization::tracking_level< T >::value == boost::serialization::track_always
Chris@16 124 || (boost::serialization::tracking_level< T >::value == boost::serialization::track_selectively
Chris@16 125 && serialized_as_pointer());
Chris@16 126 }
Chris@16 127 virtual version_type version() const {
Chris@16 128 return version_type(::boost::serialization::version< T >::value);
Chris@16 129 }
Chris@16 130 virtual bool is_polymorphic() const {
Chris@16 131 return boost::is_polymorphic< T >::value;
Chris@16 132 }
Chris@16 133 virtual ~oserializer(){}
Chris@16 134 };
Chris@16 135
Chris@16 136 #ifdef BOOST_MSVC
Chris@16 137 # pragma warning(pop)
Chris@16 138 #endif
Chris@16 139
Chris@16 140 template<class Archive, class T>
Chris@16 141 BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
Chris@16 142 basic_oarchive & ar,
Chris@16 143 const void *x
Chris@16 144 ) const {
Chris@16 145 // make sure call is routed through the highest interface that might
Chris@16 146 // be specialized by the user.
Chris@16 147 BOOST_STATIC_ASSERT(boost::is_const< T >::value == false);
Chris@16 148 boost::serialization::serialize_adl(
Chris@16 149 boost::serialization::smart_cast_reference<Archive &>(ar),
Chris@16 150 * static_cast<T *>(const_cast<void *>(x)),
Chris@16 151 version()
Chris@16 152 );
Chris@16 153 }
Chris@16 154
Chris@16 155 #ifdef BOOST_MSVC
Chris@16 156 # pragma warning(push)
Chris@16 157 # pragma warning(disable : 4511 4512)
Chris@16 158 #endif
Chris@16 159
Chris@16 160 template<class Archive, class T>
Chris@16 161 class pointer_oserializer :
Chris@16 162 public basic_pointer_oserializer
Chris@16 163 {
Chris@16 164 private:
Chris@16 165 const basic_oserializer &
Chris@16 166 get_basic_serializer() const {
Chris@16 167 return boost::serialization::singleton<
Chris@16 168 oserializer<Archive, T>
Chris@16 169 >::get_const_instance();
Chris@16 170 }
Chris@16 171 virtual BOOST_DLLEXPORT void save_object_ptr(
Chris@16 172 basic_oarchive & ar,
Chris@16 173 const void * x
Chris@16 174 ) const BOOST_USED;
Chris@16 175 public:
Chris@16 176 pointer_oserializer();
Chris@16 177 ~pointer_oserializer();
Chris@16 178 };
Chris@16 179
Chris@16 180 #ifdef BOOST_MSVC
Chris@16 181 # pragma warning(pop)
Chris@16 182 #endif
Chris@16 183
Chris@16 184 template<class Archive, class T>
Chris@16 185 BOOST_DLLEXPORT void pointer_oserializer<Archive, T>::save_object_ptr(
Chris@16 186 basic_oarchive & ar,
Chris@16 187 const void * x
Chris@16 188 ) const {
Chris@16 189 BOOST_ASSERT(NULL != x);
Chris@16 190 // make sure call is routed through the highest interface that might
Chris@16 191 // be specialized by the user.
Chris@16 192 T * t = static_cast<T *>(const_cast<void *>(x));
Chris@16 193 const unsigned int file_version = boost::serialization::version< T >::value;
Chris@16 194 Archive & ar_impl
Chris@16 195 = boost::serialization::smart_cast_reference<Archive &>(ar);
Chris@16 196 boost::serialization::save_construct_data_adl<Archive, T>(
Chris@16 197 ar_impl,
Chris@16 198 t,
Chris@16 199 file_version
Chris@16 200 );
Chris@16 201 ar_impl << boost::serialization::make_nvp(NULL, * t);
Chris@16 202 }
Chris@16 203
Chris@16 204 template<class Archive, class T>
Chris@16 205 pointer_oserializer<Archive, T>::pointer_oserializer() :
Chris@16 206 basic_pointer_oserializer(
Chris@16 207 boost::serialization::singleton<
Chris@101 208 typename
Chris@16 209 boost::serialization::type_info_implementation< T >::type
Chris@16 210 >::get_const_instance()
Chris@16 211 )
Chris@16 212 {
Chris@16 213 // make sure appropriate member function is instantiated
Chris@16 214 boost::serialization::singleton<
Chris@16 215 oserializer<Archive, T>
Chris@16 216 >::get_mutable_instance().set_bpos(this);
Chris@16 217 archive_serializer_map<Archive>::insert(this);
Chris@16 218 }
Chris@16 219
Chris@16 220 template<class Archive, class T>
Chris@16 221 pointer_oserializer<Archive, T>::~pointer_oserializer(){
Chris@16 222 archive_serializer_map<Archive>::erase(this);
Chris@16 223 }
Chris@16 224
Chris@16 225 template<class Archive>
Chris@16 226 struct save_non_pointer_type {
Chris@16 227 // note this bounces the call right back to the archive
Chris@16 228 // with no runtime overhead
Chris@16 229 struct save_primitive {
Chris@16 230 template<class T>
Chris@16 231 static void invoke(Archive & ar, const T & t){
Chris@16 232 save_access::save_primitive(ar, t);
Chris@16 233 }
Chris@16 234 };
Chris@16 235 // same as above but passes through serialization
Chris@16 236 struct save_only {
Chris@16 237 template<class T>
Chris@16 238 static void invoke(Archive & ar, const T & t){
Chris@16 239 // make sure call is routed through the highest interface that might
Chris@16 240 // be specialized by the user.
Chris@16 241 boost::serialization::serialize_adl(
Chris@16 242 ar,
Chris@16 243 const_cast<T &>(t),
Chris@16 244 ::boost::serialization::version< T >::value
Chris@16 245 );
Chris@16 246 }
Chris@16 247 };
Chris@16 248 // adds class information to the archive. This includes
Chris@16 249 // serialization level and class version
Chris@16 250 struct save_standard {
Chris@16 251 template<class T>
Chris@16 252 static void invoke(Archive &ar, const T & t){
Chris@16 253 ar.save_object(
Chris@16 254 & t,
Chris@16 255 boost::serialization::singleton<
Chris@16 256 oserializer<Archive, T>
Chris@16 257 >::get_const_instance()
Chris@16 258 );
Chris@16 259 }
Chris@16 260 };
Chris@16 261
Chris@16 262 // adds class information to the archive. This includes
Chris@16 263 // serialization level and class version
Chris@16 264 struct save_conditional {
Chris@16 265 template<class T>
Chris@16 266 static void invoke(Archive &ar, const T &t){
Chris@16 267 //if(0 == (ar.get_flags() & no_tracking))
Chris@16 268 save_standard::invoke(ar, t);
Chris@16 269 //else
Chris@16 270 // save_only::invoke(ar, t);
Chris@16 271 }
Chris@16 272 };
Chris@16 273
Chris@16 274
Chris@16 275 template<class T>
Chris@16 276 static void invoke(Archive & ar, const T & t){
Chris@16 277 typedef
Chris@101 278 typename mpl::eval_if<
Chris@16 279 // if its primitive
Chris@16 280 mpl::equal_to<
Chris@16 281 boost::serialization::implementation_level< T >,
Chris@16 282 mpl::int_<boost::serialization::primitive_type>
Chris@16 283 >,
Chris@16 284 mpl::identity<save_primitive>,
Chris@16 285 // else
Chris@101 286 typename mpl::eval_if<
Chris@16 287 // class info / version
Chris@16 288 mpl::greater_equal<
Chris@16 289 boost::serialization::implementation_level< T >,
Chris@16 290 mpl::int_<boost::serialization::object_class_info>
Chris@16 291 >,
Chris@16 292 // do standard save
Chris@16 293 mpl::identity<save_standard>,
Chris@16 294 // else
Chris@101 295 typename mpl::eval_if<
Chris@16 296 // no tracking
Chris@16 297 mpl::equal_to<
Chris@16 298 boost::serialization::tracking_level< T >,
Chris@16 299 mpl::int_<boost::serialization::track_never>
Chris@16 300 >,
Chris@16 301 // do a fast save
Chris@16 302 mpl::identity<save_only>,
Chris@16 303 // else
Chris@16 304 // do a fast save only tracking is turned off
Chris@16 305 mpl::identity<save_conditional>
Chris@16 306 > > >::type typex;
Chris@16 307 check_object_versioning< T >();
Chris@16 308 typex::invoke(ar, t);
Chris@16 309 }
Chris@16 310 template<class T>
Chris@16 311 static void invoke(Archive & ar, T & t){
Chris@16 312 check_object_level< T >();
Chris@16 313 check_object_tracking< T >();
Chris@16 314 invoke(ar, const_cast<const T &>(t));
Chris@16 315 }
Chris@16 316 };
Chris@16 317
Chris@16 318 template<class Archive>
Chris@16 319 struct save_pointer_type {
Chris@16 320 struct abstract
Chris@16 321 {
Chris@16 322 template<class T>
Chris@16 323 static const basic_pointer_oserializer * register_type(Archive & /* ar */){
Chris@16 324 // it has? to be polymorphic
Chris@16 325 BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value);
Chris@16 326 return NULL;
Chris@16 327 }
Chris@16 328 };
Chris@16 329
Chris@16 330 struct non_abstract
Chris@16 331 {
Chris@16 332 template<class T>
Chris@16 333 static const basic_pointer_oserializer * register_type(Archive & ar){
Chris@16 334 return ar.register_type(static_cast<T *>(NULL));
Chris@16 335 }
Chris@16 336 };
Chris@16 337
Chris@16 338 template<class T>
Chris@16 339 static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){
Chris@16 340 // there should never be any need to save an abstract polymorphic
Chris@16 341 // class pointer. Inhibiting code generation for this
Chris@16 342 // permits abstract base classes to be used - note: exception
Chris@16 343 // virtual serialize functions used for plug-ins
Chris@16 344 typedef
Chris@101 345 typename mpl::eval_if<
Chris@16 346 boost::serialization::is_abstract< T >,
Chris@16 347 mpl::identity<abstract>,
Chris@16 348 mpl::identity<non_abstract>
Chris@16 349 >::type typex;
Chris@16 350 return typex::template register_type< T >(ar);
Chris@16 351 }
Chris@16 352
Chris@16 353 struct non_polymorphic
Chris@16 354 {
Chris@16 355 template<class T>
Chris@16 356 static void save(
Chris@16 357 Archive &ar,
Chris@16 358 T & t
Chris@16 359 ){
Chris@16 360 const basic_pointer_oserializer & bpos =
Chris@16 361 boost::serialization::singleton<
Chris@16 362 pointer_oserializer<Archive, T>
Chris@16 363 >::get_const_instance();
Chris@16 364 // save the requested pointer type
Chris@16 365 ar.save_pointer(& t, & bpos);
Chris@16 366 }
Chris@16 367 };
Chris@16 368
Chris@16 369 struct polymorphic
Chris@16 370 {
Chris@16 371 template<class T>
Chris@16 372 static void save(
Chris@16 373 Archive &ar,
Chris@16 374 T & t
Chris@16 375 ){
Chris@101 376 typename
Chris@16 377 boost::serialization::type_info_implementation< T >::type const
Chris@16 378 & i = boost::serialization::singleton<
Chris@101 379 typename
Chris@16 380 boost::serialization::type_info_implementation< T >::type
Chris@16 381 >::get_const_instance();
Chris@16 382
Chris@16 383 boost::serialization::extended_type_info const * const this_type = & i;
Chris@16 384
Chris@16 385 // retrieve the true type of the object pointed to
Chris@16 386 // if this assertion fails its an error in this library
Chris@16 387 BOOST_ASSERT(NULL != this_type);
Chris@16 388
Chris@16 389 const boost::serialization::extended_type_info * true_type =
Chris@16 390 i.get_derived_extended_type_info(t);
Chris@16 391
Chris@16 392 // note:if this exception is thrown, be sure that derived pointer
Chris@16 393 // is either registered or exported.
Chris@16 394 if(NULL == true_type){
Chris@16 395 boost::serialization::throw_exception(
Chris@16 396 archive_exception(
Chris@16 397 archive_exception::unregistered_class,
Chris@16 398 "derived class not registered or exported"
Chris@16 399 )
Chris@16 400 );
Chris@16 401 }
Chris@16 402
Chris@16 403 // if its not a pointer to a more derived type
Chris@16 404 const void *vp = static_cast<const void *>(&t);
Chris@16 405 if(*this_type == *true_type){
Chris@16 406 const basic_pointer_oserializer * bpos = register_type(ar, t);
Chris@16 407 ar.save_pointer(vp, bpos);
Chris@16 408 return;
Chris@16 409 }
Chris@16 410 // convert pointer to more derived type. if this is thrown
Chris@16 411 // it means that the base/derived relationship hasn't be registered
Chris@16 412 vp = serialization::void_downcast(
Chris@16 413 *true_type,
Chris@16 414 *this_type,
Chris@16 415 static_cast<const void *>(&t)
Chris@16 416 );
Chris@16 417 if(NULL == vp){
Chris@16 418 boost::serialization::throw_exception(
Chris@16 419 archive_exception(
Chris@16 420 archive_exception::unregistered_cast,
Chris@16 421 true_type->get_debug_info(),
Chris@16 422 this_type->get_debug_info()
Chris@16 423 )
Chris@16 424 );
Chris@16 425 }
Chris@16 426
Chris@16 427 // since true_type is valid, and this only gets made if the
Chris@16 428 // pointer oserializer object has been created, this should never
Chris@16 429 // fail
Chris@16 430 const basic_pointer_oserializer * bpos
Chris@16 431 = static_cast<const basic_pointer_oserializer *>(
Chris@16 432 boost::serialization::singleton<
Chris@16 433 archive_serializer_map<Archive>
Chris@16 434 >::get_const_instance().find(*true_type)
Chris@16 435 );
Chris@16 436 BOOST_ASSERT(NULL != bpos);
Chris@16 437 if(NULL == bpos)
Chris@16 438 boost::serialization::throw_exception(
Chris@16 439 archive_exception(
Chris@16 440 archive_exception::unregistered_class,
Chris@16 441 "derived class not registered or exported"
Chris@16 442 )
Chris@16 443 );
Chris@16 444 ar.save_pointer(vp, bpos);
Chris@16 445 }
Chris@16 446 };
Chris@16 447
Chris@16 448 template<class T>
Chris@16 449 static void save(
Chris@16 450 Archive & ar,
Chris@16 451 const T & t
Chris@16 452 ){
Chris@16 453 check_pointer_level< T >();
Chris@16 454 check_pointer_tracking< T >();
Chris@101 455 typedef typename mpl::eval_if<
Chris@16 456 is_polymorphic< T >,
Chris@16 457 mpl::identity<polymorphic>,
Chris@16 458 mpl::identity<non_polymorphic>
Chris@16 459 >::type type;
Chris@16 460 type::save(ar, const_cast<T &>(t));
Chris@16 461 }
Chris@16 462
Chris@16 463 template<class TPtr>
Chris@16 464 static void invoke(Archive &ar, const TPtr t){
Chris@16 465 register_type(ar, * t);
Chris@16 466 if(NULL == t){
Chris@16 467 basic_oarchive & boa
Chris@16 468 = boost::serialization::smart_cast_reference<basic_oarchive &>(ar);
Chris@16 469 boa.save_null_pointer();
Chris@16 470 save_access::end_preamble(ar);
Chris@16 471 return;
Chris@16 472 }
Chris@16 473 save(ar, * t);
Chris@16 474 }
Chris@16 475 };
Chris@16 476
Chris@16 477 template<class Archive>
Chris@16 478 struct save_enum_type
Chris@16 479 {
Chris@16 480 template<class T>
Chris@16 481 static void invoke(Archive &ar, const T &t){
Chris@16 482 // convert enum to integers on save
Chris@16 483 const int i = static_cast<int>(t);
Chris@16 484 ar << boost::serialization::make_nvp(NULL, i);
Chris@16 485 }
Chris@16 486 };
Chris@16 487
Chris@16 488 template<class Archive>
Chris@16 489 struct save_array_type
Chris@16 490 {
Chris@16 491 template<class T>
Chris@16 492 static void invoke(Archive &ar, const T &t){
Chris@101 493 typedef typename boost::remove_extent< T >::type value_type;
Chris@16 494
Chris@16 495 save_access::end_preamble(ar);
Chris@16 496 // consider alignment
Chris@16 497 std::size_t c = sizeof(t) / (
Chris@16 498 static_cast<const char *>(static_cast<const void *>(&t[1]))
Chris@16 499 - static_cast<const char *>(static_cast<const void *>(&t[0]))
Chris@16 500 );
Chris@16 501 boost::serialization::collection_size_type count(c);
Chris@16 502 ar << BOOST_SERIALIZATION_NVP(count);
Chris@16 503 ar << serialization::make_array(static_cast<value_type const*>(&t[0]),count);
Chris@16 504 }
Chris@16 505 };
Chris@16 506
Chris@16 507 } // detail
Chris@16 508
Chris@16 509 template<class Archive, class T>
Chris@16 510 inline void save(Archive & ar, /*const*/ T &t){
Chris@16 511 typedef
Chris@101 512 typename mpl::eval_if<is_pointer< T >,
Chris@16 513 mpl::identity<detail::save_pointer_type<Archive> >,
Chris@16 514 //else
Chris@101 515 typename mpl::eval_if<is_enum< T >,
Chris@16 516 mpl::identity<detail::save_enum_type<Archive> >,
Chris@16 517 //else
Chris@101 518 typename mpl::eval_if<is_array< T >,
Chris@16 519 mpl::identity<detail::save_array_type<Archive> >,
Chris@16 520 //else
Chris@16 521 mpl::identity<detail::save_non_pointer_type<Archive> >
Chris@16 522 >
Chris@16 523 >
Chris@16 524 >::type typex;
Chris@16 525 typex::invoke(ar, t);
Chris@16 526 }
Chris@16 527
Chris@16 528 } // namespace archive
Chris@16 529 } // namespace boost
Chris@16 530
Chris@16 531 #endif // BOOST_ARCHIVE_OSERIALIZER_HPP