base_object.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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) && (_MSC_VER >= 1020)
  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/bool.hpp>
  22. #include <boost/mpl/identity.hpp>
  23. #include <boost/type_traits/is_base_and_derived.hpp>
  24. #include <boost/type_traits/is_pointer.hpp>
  25. #include <boost/type_traits/is_const.hpp>
  26. #include <boost/type_traits/is_polymorphic.hpp>
  27. #include <boost/static_assert.hpp>
  28. #include <boost/serialization/access.hpp>
  29. #include <boost/serialization/force_include.hpp>
  30. #include <boost/serialization/void_cast_fwd.hpp>
  31. namespace boost {
  32. namespace serialization {
  33. namespace detail
  34. {
  35. // get the base type for a given derived type
  36. // preserving the const-ness
  37. template<class B, class D>
  38. struct base_cast
  39. {
  40. typedef BOOST_DEDUCED_TYPENAME
  41. mpl::if_<
  42. is_const<D>,
  43. const B,
  44. B
  45. >::type type;
  46. BOOST_STATIC_ASSERT(is_const<type>::value == is_const<D>::value);
  47. };
  48. // only register void casts if the types are polymorphic
  49. template<class Base, class Derived>
  50. struct base_register
  51. {
  52. struct polymorphic {
  53. static void const * invoke(){
  54. Base const * const b = 0;
  55. Derived const * const d = 0;
  56. return & void_cast_register(d, b);
  57. }
  58. };
  59. struct non_polymorphic {
  60. static void const * invoke(){
  61. return 0;
  62. }
  63. };
  64. static void const * invoke(){
  65. typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
  66. is_polymorphic<Base>,
  67. mpl::identity<polymorphic>,
  68. mpl::identity<non_polymorphic>
  69. >::type type;
  70. return type::invoke();
  71. }
  72. };
  73. } // namespace detail
  74. #if defined(__BORLANDC__) && __BORLANDC__ < 0x610
  75. template<class Base, class Derived>
  76. const Base &
  77. base_object(const Derived & d)
  78. {
  79. BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
  80. detail::base_register<Base, Derived>::invoke();
  81. return access::cast_reference<const Base, Derived>(d);
  82. }
  83. #else
  84. template<class Base, class Derived>
  85. BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type &
  86. base_object(Derived &d)
  87. {
  88. BOOST_STATIC_ASSERT(( is_base_and_derived<Base,Derived>::value));
  89. BOOST_STATIC_ASSERT(! is_pointer<Derived>::value);
  90. typedef BOOST_DEDUCED_TYPENAME detail::base_cast<Base, Derived>::type type;
  91. detail::base_register<type, Derived>::invoke();
  92. return access::cast_reference<type, Derived>(d);
  93. }
  94. #endif
  95. } // namespace serialization
  96. } // namespace boost
  97. #endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP