base_object.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP
  2. #define BOOST_SERIALIZATION_BASE_OBJECT_HPP
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER)
  5. # pragma once
  6. #endif
  7. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  8. // base_object.hpp:
  9. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  10. // Use, modification and distribution is subject to the Boost Software
  11. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. // See http://www.boost.org for updates, documentation, and revision history.
  14. // if no archive headers have been included this is a no op
  15. // this is to permit BOOST_EXPORT etc to be included in a
  16. // file declaration header
  17. #include <boost/config.hpp>
  18. #include <boost/detail/workaround.hpp>
  19. #include <boost/mpl/eval_if.hpp>
  20. #include <boost/mpl/int.hpp>
  21. #include <boost/mpl/identity.hpp>
  22. #include <boost/type_traits/is_base_and_derived.hpp>
  23. #include <boost/type_traits/is_pointer.hpp>
  24. #include <boost/type_traits/is_const.hpp>
  25. #include <boost/type_traits/is_polymorphic.hpp>
  26. #include <boost/static_assert.hpp>
  27. #include <boost/serialization/access.hpp>
  28. #include <boost/serialization/force_include.hpp>
  29. #include <boost/serialization/void_cast_fwd.hpp>
  30. namespace boost {
  31. namespace serialization {
  32. namespace detail
  33. {
  34. // get the base type for a given derived type
  35. // preserving the const-ness
  36. template<class B, class D>
  37. struct base_cast
  38. {
  39. typedef typename
  40. mpl::if_<
  41. is_const<D>,
  42. const B,
  43. B
  44. >::type type;
  45. BOOST_STATIC_ASSERT(is_const<type>::value == is_const<D>::value);
  46. };
  47. // only register void casts if the types are polymorphic
  48. template<class Base, class Derived>
  49. struct base_register
  50. {
  51. struct polymorphic {
  52. static void const * invoke(){
  53. Base const * const b = 0;
  54. Derived const * const d = 0;
  55. return & void_cast_register(d, b);
  56. }
  57. };
  58. struct non_polymorphic {
  59. static void const * invoke(){
  60. return 0;
  61. }
  62. };
  63. static void const * invoke(){
  64. typedef typename mpl::eval_if<
  65. is_polymorphic<Base>,
  66. mpl::identity<polymorphic>,
  67. mpl::identity<non_polymorphic>
  68. >::type type;
  69. return type::invoke();
  70. }
  71. };
  72. } // namespace detail
  73. template<class Base, class Derived>
  74. typename detail::base_cast<Base, Derived>::type &
  75. base_object(Derived &d)
  76. {
  77. BOOST_STATIC_ASSERT(( is_base_and_derived<Base,Derived>::value));
  78. BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
  79. typedef typename detail::base_cast<Base, Derived>::type type;
  80. detail::base_register<type, Derived>::invoke();
  81. return access::cast_reference<type, Derived>(d);
  82. }
  83. } // namespace serialization
  84. } // namespace boost
  85. #endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP