Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/archive/detail/iserializer.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
comparison
equal
deleted
inserted
replaced
100:793467b5e61c | 101:c530137014c0 |
---|---|
1 #ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP | 1 #ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP |
2 #define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP | 2 #define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP |
3 | 3 |
4 // MS compatible compilers support #pragma once | 4 // MS compatible compilers support #pragma once |
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | 5 #if defined(_MSC_VER) |
6 # pragma once | 6 # pragma once |
7 #pragma inline_depth(511) | 7 #pragma inline_depth(511) |
8 #pragma inline_recursion(on) | 8 #pragma inline_recursion(on) |
9 #endif | 9 #endif |
10 | 10 |
21 // http://www.boost.org/LICENSE_1_0.txt) | 21 // http://www.boost.org/LICENSE_1_0.txt) |
22 | 22 |
23 // See http://www.boost.org for updates, documentation, and revision history. | 23 // See http://www.boost.org for updates, documentation, and revision history. |
24 | 24 |
25 #include <new> // for placement new | 25 #include <new> // for placement new |
26 #include <memory> // for auto_ptr | |
27 #include <cstddef> // size_t, NULL | 26 #include <cstddef> // size_t, NULL |
28 | 27 |
29 #include <boost/config.hpp> | 28 #include <boost/config.hpp> |
30 #include <boost/detail/workaround.hpp> | 29 #include <boost/detail/workaround.hpp> |
31 #if defined(BOOST_NO_STDC_NAMESPACE) | 30 #if defined(BOOST_NO_STDC_NAMESPACE) |
39 #include <boost/mpl/eval_if.hpp> | 38 #include <boost/mpl/eval_if.hpp> |
40 #include <boost/mpl/identity.hpp> | 39 #include <boost/mpl/identity.hpp> |
41 #include <boost/mpl/greater_equal.hpp> | 40 #include <boost/mpl/greater_equal.hpp> |
42 #include <boost/mpl/equal_to.hpp> | 41 #include <boost/mpl/equal_to.hpp> |
43 #include <boost/mpl/bool.hpp> | 42 #include <boost/mpl/bool.hpp> |
44 #include <boost/detail/no_exceptions_support.hpp> | 43 #include <boost/core/no_exceptions_support.hpp> |
45 | 44 |
46 #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO | 45 #ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO |
47 #include <boost/serialization/extended_type_info_typeid.hpp> | 46 #include <boost/serialization/extended_type_info_typeid.hpp> |
48 #endif | 47 #endif |
49 #include <boost/serialization/throw_exception.hpp> | 48 #include <boost/serialization/throw_exception.hpp> |
56 #include <boost/type_traits/remove_const.hpp> | 55 #include <boost/type_traits/remove_const.hpp> |
57 #include <boost/type_traits/remove_extent.hpp> | 56 #include <boost/type_traits/remove_extent.hpp> |
58 #include <boost/type_traits/is_polymorphic.hpp> | 57 #include <boost/type_traits/is_polymorphic.hpp> |
59 | 58 |
60 #include <boost/serialization/assume_abstract.hpp> | 59 #include <boost/serialization/assume_abstract.hpp> |
61 | |
62 #define DONT_USE_HAS_NEW_OPERATOR ( \ | 60 #define DONT_USE_HAS_NEW_OPERATOR ( \ |
63 defined(__BORLANDC__) \ | 61 defined(__BORLANDC__) \ |
64 || BOOST_WORKAROUND(__IBMCPP__, < 1210) \ | 62 || BOOST_WORKAROUND(__IBMCPP__, < 1210) \ |
65 || defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) \ | |
66 || defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \ | 63 || defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \ |
67 ) | 64 ) |
68 | |
69 #if ! DONT_USE_HAS_NEW_OPERATOR | 65 #if ! DONT_USE_HAS_NEW_OPERATOR |
70 #include <boost/type_traits/has_new_operator.hpp> | 66 #include <boost/type_traits/has_new_operator.hpp> |
71 #endif | 67 #endif |
72 | 68 |
73 #include <boost/serialization/serialization.hpp> | 69 #include <boost/serialization/serialization.hpp> |
125 protected: | 121 protected: |
126 // protected constructor since it's always created by singleton | 122 // protected constructor since it's always created by singleton |
127 explicit iserializer() : | 123 explicit iserializer() : |
128 basic_iserializer( | 124 basic_iserializer( |
129 boost::serialization::singleton< | 125 boost::serialization::singleton< |
130 BOOST_DEDUCED_TYPENAME | 126 typename |
131 boost::serialization::type_info_implementation< T >::type | 127 boost::serialization::type_info_implementation< T >::type |
132 >::get_const_instance() | 128 >::get_const_instance() |
133 ) | 129 ) |
134 {} | 130 {} |
135 public: | 131 public: |
195 #ifdef BOOST_MSVC | 191 #ifdef BOOST_MSVC |
196 # pragma warning(push) | 192 # pragma warning(push) |
197 # pragma warning(disable : 4511 4512) | 193 # pragma warning(disable : 4511 4512) |
198 #endif | 194 #endif |
199 | 195 |
196 // the purpose of this code is to allocate memory for an object | |
197 // without requiring the constructor to be called. Presumably | |
198 // the allocated object will be subsequently initialized with | |
199 // "placement new". | |
200 // note: we have the boost type trait has_new_operator but we | |
201 // have no corresponding has_delete_operator. So we presume | |
202 // that the former being true would imply that the a delete | |
203 // operator is also defined for the class T. | |
204 | |
205 template<class T> | |
206 struct heap_allocation { | |
207 // boost::has_new_operator< T > doesn't work on these compilers | |
208 #if DONT_USE_HAS_NEW_OPERATOR | |
209 // This doesn't handle operator new overload for class T | |
210 static T * invoke_new(){ | |
211 return static_cast<T *>(operator new(sizeof(T))); | |
212 } | |
213 static void invoke_delete(T *t){ | |
214 (operator delete(t)); | |
215 } | |
216 #else | |
217 // note: we presume that a true value for has_new_operator | |
218 // implies the existence of a class specific delete operator as well | |
219 // as a class specific new operator. | |
220 struct has_new_operator { | |
221 static T * invoke_new() { | |
222 return static_cast<T *>((T::operator new)(sizeof(T))); | |
223 } | |
224 static void invoke_delete(T * t) { | |
225 // if compilation fails here, the likely cause that the class | |
226 // T has a class specific new operator but no class specific | |
227 // delete operator which matches the following signature. Fix | |
228 // your program to have this. Note that adding operator delete | |
229 // with only one parameter doesn't seem correct to me since | |
230 // the standard(3.7.4.2) says " | |
231 // "If a class T has a member deallocation function named | |
232 // 'operator delete' with exactly one parameter, then that function | |
233 // is a usual (non-placement) deallocation function" which I take | |
234 // to mean that it will call the destructor of type T which we don't | |
235 // want to do here. | |
236 // Note: reliance upon automatic conversion from T * to void * here | |
237 (T::operator delete)(t, sizeof(T)); | |
238 } | |
239 }; | |
240 struct doesnt_have_new_operator { | |
241 static T* invoke_new() { | |
242 return static_cast<T *>(operator new(sizeof(T))); | |
243 } | |
244 static void invoke_delete(T * t) { | |
245 // Note: I'm reliance upon automatic conversion from T * to void * here | |
246 (operator delete)(t); | |
247 } | |
248 }; | |
249 static T * invoke_new() { | |
250 typedef typename | |
251 mpl::eval_if< | |
252 boost::has_new_operator< T >, | |
253 mpl::identity<has_new_operator >, | |
254 mpl::identity<doesnt_have_new_operator > | |
255 >::type typex; | |
256 return typex::invoke_new(); | |
257 } | |
258 static void invoke_delete(T *t) { | |
259 typedef typename | |
260 mpl::eval_if< | |
261 boost::has_new_operator< T >, | |
262 mpl::identity<has_new_operator >, | |
263 mpl::identity<doesnt_have_new_operator > | |
264 >::type typex; | |
265 typex::invoke_delete(t); | |
266 } | |
267 #endif | |
268 explicit heap_allocation(){ | |
269 m_p = invoke_new(); | |
270 } | |
271 ~heap_allocation(){ | |
272 if (0 != m_p) | |
273 invoke_delete(m_p); | |
274 } | |
275 T* get() const { | |
276 return m_p; | |
277 } | |
278 | |
279 T* release() { | |
280 T* p = m_p; | |
281 m_p = 0; | |
282 return p; | |
283 } | |
284 private: | |
285 T* m_p; | |
286 }; | |
287 | |
200 template<class Archive, class T> | 288 template<class Archive, class T> |
201 class pointer_iserializer : | 289 class pointer_iserializer : |
202 public basic_pointer_iserializer | 290 public basic_pointer_iserializer |
203 { | 291 { |
204 private: | 292 private: |
293 virtual void * heap_allocation() const { | |
294 detail::heap_allocation<T> h; | |
295 T * t = h.get(); | |
296 h.release(); | |
297 return t; | |
298 } | |
205 virtual const basic_iserializer & get_basic_serializer() const { | 299 virtual const basic_iserializer & get_basic_serializer() const { |
206 return boost::serialization::singleton< | 300 return boost::serialization::singleton< |
207 iserializer<Archive, T> | 301 iserializer<Archive, T> |
208 >::get_const_instance(); | 302 >::get_const_instance(); |
209 } | 303 } |
210 BOOST_DLLEXPORT virtual void load_object_ptr( | 304 BOOST_DLLEXPORT virtual void load_object_ptr( |
211 basic_iarchive & ar, | 305 basic_iarchive & ar, |
212 void * & x, | 306 void * x, |
213 const unsigned int file_version | 307 const unsigned int file_version |
214 ) const BOOST_USED; | 308 ) const BOOST_USED; |
215 protected: | 309 protected: |
216 // this should alway be a singleton so make the constructor protected | 310 // this should alway be a singleton so make the constructor protected |
217 pointer_iserializer(); | 311 pointer_iserializer(); |
220 | 314 |
221 #ifdef BOOST_MSVC | 315 #ifdef BOOST_MSVC |
222 # pragma warning(pop) | 316 # pragma warning(pop) |
223 #endif | 317 #endif |
224 | 318 |
225 // note trick to be sure that operator new is using class specific | |
226 // version if such exists. Due to Peter Dimov. | |
227 // note: the following fails if T has no default constructor. | |
228 // otherwise it would have been ideal | |
229 //struct heap_allocator : public T | |
230 //{ | |
231 // T * invoke(){ | |
232 // return ::new(sizeof(T)); | |
233 // } | |
234 //} | |
235 | |
236 template<class T> | |
237 struct heap_allocator | |
238 { | |
239 // boost::has_new_operator< T > doesn't work on these compilers | |
240 #if DONT_USE_HAS_NEW_OPERATOR | |
241 // This doesn't handle operator new overload for class T | |
242 static T * invoke(){ | |
243 return static_cast<T *>(operator new(sizeof(T))); | |
244 } | |
245 #else | |
246 struct has_new_operator { | |
247 static T* invoke() { | |
248 return static_cast<T *>((T::operator new)(sizeof(T))); | |
249 } | |
250 }; | |
251 struct doesnt_have_new_operator { | |
252 static T* invoke() { | |
253 return static_cast<T *>(operator new(sizeof(T))); | |
254 } | |
255 }; | |
256 static T * invoke() { | |
257 typedef BOOST_DEDUCED_TYPENAME | |
258 mpl::eval_if< | |
259 boost::has_new_operator< T >, | |
260 mpl::identity<has_new_operator >, | |
261 mpl::identity<doesnt_have_new_operator > | |
262 >::type typex; | |
263 return typex::invoke(); | |
264 } | |
265 #endif | |
266 }; | |
267 | |
268 // due to Martin Ecker | |
269 template <typename T> | |
270 class auto_ptr_with_deleter | |
271 { | |
272 public: | |
273 explicit auto_ptr_with_deleter(T* p) : | |
274 m_p(p) | |
275 {} | |
276 ~auto_ptr_with_deleter(){ | |
277 if (m_p) | |
278 boost::serialization::access::destroy(m_p); | |
279 } | |
280 T* get() const { | |
281 return m_p; | |
282 } | |
283 | |
284 T* release() { | |
285 T* p = m_p; | |
286 m_p = NULL; | |
287 return p; | |
288 } | |
289 private: | |
290 T* m_p; | |
291 }; | |
292 | |
293 // note: BOOST_DLLEXPORT is so that code for polymorphic class | 319 // note: BOOST_DLLEXPORT is so that code for polymorphic class |
294 // serialized only through base class won't get optimized out | 320 // serialized only through base class won't get optimized out |
295 template<class Archive, class T> | 321 template<class Archive, class T> |
296 BOOST_DLLEXPORT void pointer_iserializer<Archive, T>::load_object_ptr( | 322 BOOST_DLLEXPORT void pointer_iserializer<Archive, T>::load_object_ptr( |
297 basic_iarchive & ar, | 323 basic_iarchive & ar, |
298 void * & x, | 324 void * t, |
299 const unsigned int file_version | 325 const unsigned int file_version |
300 ) const | 326 ) const |
301 { | 327 { |
302 Archive & ar_impl = | 328 Archive & ar_impl = |
303 boost::serialization::smart_cast_reference<Archive &>(ar); | 329 boost::serialization::smart_cast_reference<Archive &>(ar); |
304 | 330 |
305 auto_ptr_with_deleter< T > ap(heap_allocator< T >::invoke()); | 331 // note that the above will throw std::bad_alloc if the allocation |
306 if(NULL == ap.get()) | 332 // fails so we don't have to address this contingency here. |
307 boost::serialization::throw_exception(std::bad_alloc()) ; | |
308 | |
309 T * t = ap.get(); | |
310 x = t; | |
311 | 333 |
312 // catch exception during load_construct_data so that we don't | 334 // catch exception during load_construct_data so that we don't |
313 // automatically delete the t which is most likely not fully | 335 // automatically delete the t which is most likely not fully |
314 // constructed | 336 // constructed |
315 BOOST_TRY { | 337 BOOST_TRY { |
316 // this addresses an obscure situtation that occurs when | 338 // this addresses an obscure situation that occurs when |
317 // load_constructor de-serializes something through a pointer. | 339 // load_constructor de-serializes something through a pointer. |
318 ar.next_object_pointer(t); | 340 ar.next_object_pointer(t); |
319 boost::serialization::load_construct_data_adl<Archive, T>( | 341 boost::serialization::load_construct_data_adl<Archive, T>( |
320 ar_impl, | 342 ar_impl, |
321 t, | 343 static_cast<T *>(t), |
322 file_version | 344 file_version |
323 ); | 345 ); |
324 } | 346 } |
325 BOOST_CATCH(...){ | 347 BOOST_CATCH(...){ |
326 ap.release(); | 348 // if we get here the load_construct failed. The heap_allocation |
349 // will be automatically deleted so we don't have to do anything | |
350 // special here. | |
327 BOOST_RETHROW; | 351 BOOST_RETHROW; |
328 } | 352 } |
329 BOOST_CATCH_END | 353 BOOST_CATCH_END |
330 | 354 |
331 ar_impl >> boost::serialization::make_nvp(NULL, * t); | 355 ar_impl >> boost::serialization::make_nvp(NULL, * static_cast<T *>(t)); |
332 ap.release(); | |
333 } | 356 } |
334 | 357 |
335 template<class Archive, class T> | 358 template<class Archive, class T> |
336 pointer_iserializer<Archive, T>::pointer_iserializer() : | 359 pointer_iserializer<Archive, T>::pointer_iserializer() : |
337 basic_pointer_iserializer( | 360 basic_pointer_iserializer( |
338 boost::serialization::singleton< | 361 boost::serialization::singleton< |
339 BOOST_DEDUCED_TYPENAME | 362 typename |
340 boost::serialization::type_info_implementation< T >::type | 363 boost::serialization::type_info_implementation< T >::type |
341 >::get_const_instance() | 364 >::get_const_instance() |
342 ) | 365 ) |
343 { | 366 { |
344 boost::serialization::singleton< | 367 boost::serialization::singleton< |
403 } | 426 } |
404 }; | 427 }; |
405 | 428 |
406 template<class T> | 429 template<class T> |
407 static void invoke(Archive & ar, T &t){ | 430 static void invoke(Archive & ar, T &t){ |
408 typedef BOOST_DEDUCED_TYPENAME mpl::eval_if< | 431 typedef typename mpl::eval_if< |
409 // if its primitive | 432 // if its primitive |
410 mpl::equal_to< | 433 mpl::equal_to< |
411 boost::serialization::implementation_level< T >, | 434 boost::serialization::implementation_level< T >, |
412 mpl::int_<boost::serialization::primitive_type> | 435 mpl::int_<boost::serialization::primitive_type> |
413 >, | 436 >, |
414 mpl::identity<load_primitive>, | 437 mpl::identity<load_primitive>, |
415 // else | 438 // else |
416 BOOST_DEDUCED_TYPENAME mpl::eval_if< | 439 typename mpl::eval_if< |
417 // class info / version | 440 // class info / version |
418 mpl::greater_equal< | 441 mpl::greater_equal< |
419 boost::serialization::implementation_level< T >, | 442 boost::serialization::implementation_level< T >, |
420 mpl::int_<boost::serialization::object_class_info> | 443 mpl::int_<boost::serialization::object_class_info> |
421 >, | 444 >, |
422 // do standard load | 445 // do standard load |
423 mpl::identity<load_standard>, | 446 mpl::identity<load_standard>, |
424 // else | 447 // else |
425 BOOST_DEDUCED_TYPENAME mpl::eval_if< | 448 typename mpl::eval_if< |
426 // no tracking | 449 // no tracking |
427 mpl::equal_to< | 450 mpl::equal_to< |
428 boost::serialization::tracking_level< T >, | 451 boost::serialization::tracking_level< T >, |
429 mpl::int_<boost::serialization::track_never> | 452 mpl::int_<boost::serialization::track_never> |
430 >, | 453 >, |
464 static const basic_pointer_iserializer * register_type(Archive &ar, const T & /*t*/){ | 487 static const basic_pointer_iserializer * register_type(Archive &ar, const T & /*t*/){ |
465 // there should never be any need to load an abstract polymorphic | 488 // there should never be any need to load an abstract polymorphic |
466 // class pointer. Inhibiting code generation for this | 489 // class pointer. Inhibiting code generation for this |
467 // permits abstract base classes to be used - note: exception | 490 // permits abstract base classes to be used - note: exception |
468 // virtual serialize functions used for plug-ins | 491 // virtual serialize functions used for plug-ins |
469 typedef BOOST_DEDUCED_TYPENAME | 492 typedef typename |
470 mpl::eval_if< | 493 mpl::eval_if< |
471 boost::serialization::is_abstract<const T>, | 494 boost::serialization::is_abstract<const T>, |
472 boost::mpl::identity<abstract>, | 495 boost::mpl::identity<abstract>, |
473 boost::mpl::identity<non_abstract> | 496 boost::mpl::identity<non_abstract> |
474 >::type typex; | 497 >::type typex; |
480 const boost::serialization::extended_type_info & eti, | 503 const boost::serialization::extended_type_info & eti, |
481 void const * const t, | 504 void const * const t, |
482 const T & | 505 const T & |
483 ) { | 506 ) { |
484 // tweak the pointer back to the base class | 507 // tweak the pointer back to the base class |
485 return static_cast<T *>( | 508 void * upcast = const_cast<void *>( |
486 const_cast<void *>( | 509 boost::serialization::void_upcast( |
487 boost::serialization::void_upcast( | 510 eti, |
488 eti, | 511 boost::serialization::singleton< |
489 boost::serialization::singleton< | 512 typename |
490 BOOST_DEDUCED_TYPENAME | 513 boost::serialization::type_info_implementation< T >::type |
491 boost::serialization::type_info_implementation< T >::type | 514 >::get_const_instance(), |
492 >::get_const_instance(), | 515 t |
493 t | |
494 ) | |
495 ) | 516 ) |
496 ); | 517 ); |
518 if(NULL == upcast) | |
519 boost::serialization::throw_exception( | |
520 archive_exception(archive_exception::unregistered_class) | |
521 ); | |
522 return static_cast<T *>(upcast); | |
497 } | 523 } |
498 | 524 |
499 template<class T> | 525 template<class T> |
500 static void check_load(T & /* t */){ | 526 static void check_load(T & /* t */){ |
501 check_pointer_level< T >(); | 527 check_pointer_level< T >(); |
542 | 568 |
543 template<class Archive> | 569 template<class Archive> |
544 struct load_array_type { | 570 struct load_array_type { |
545 template<class T> | 571 template<class T> |
546 static void invoke(Archive &ar, T &t){ | 572 static void invoke(Archive &ar, T &t){ |
547 typedef BOOST_DEDUCED_TYPENAME remove_extent< T >::type value_type; | 573 typedef typename remove_extent< T >::type value_type; |
548 | 574 |
549 // convert integers to correct enum to load | 575 // convert integers to correct enum to load |
550 // determine number of elements in the array. Consider the | 576 // determine number of elements in the array. Consider the |
551 // fact that some machines will align elements on boundries | 577 // fact that some machines will align elements on boundries |
552 // other than characters. | 578 // other than characters. |
574 // const object with a compiler that doesn't have correct | 600 // const object with a compiler that doesn't have correct |
575 // funtion template ordering. On other compilers, this is | 601 // funtion template ordering. On other compilers, this is |
576 // handled below. | 602 // handled below. |
577 detail::check_const_loading< T >(); | 603 detail::check_const_loading< T >(); |
578 typedef | 604 typedef |
579 BOOST_DEDUCED_TYPENAME mpl::eval_if<is_pointer< T >, | 605 typename mpl::eval_if<is_pointer< T >, |
580 mpl::identity<detail::load_pointer_type<Archive> > | 606 mpl::identity<detail::load_pointer_type<Archive> > |
581 ,//else | 607 ,//else |
582 BOOST_DEDUCED_TYPENAME mpl::eval_if<is_array< T >, | 608 typename mpl::eval_if<is_array< T >, |
583 mpl::identity<detail::load_array_type<Archive> > | 609 mpl::identity<detail::load_array_type<Archive> > |
584 ,//else | 610 ,//else |
585 BOOST_DEDUCED_TYPENAME mpl::eval_if<is_enum< T >, | 611 typename mpl::eval_if<is_enum< T >, |
586 mpl::identity<detail::load_enum_type<Archive> > | 612 mpl::identity<detail::load_enum_type<Archive> > |
587 ,//else | 613 ,//else |
588 mpl::identity<detail::load_non_pointer_type<Archive> > | 614 mpl::identity<detail::load_non_pointer_type<Archive> > |
589 > | 615 > |
590 > | 616 > |