test_void_cast.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_void_cast.cpp: test implementation of run-time casting of void pointers
  3. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  4. // Use, modification and distribution is subject to the Boost Software
  5. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // <gennadiy.rozental@tfn.com>
  8. #include <cstddef> // NULL
  9. #include "test_tools.hpp"
  10. #include <boost/serialization/extended_type_info_typeid.hpp>
  11. #include <boost/serialization/void_cast.hpp>
  12. #include <boost/serialization/singleton.hpp>
  13. class Base1
  14. {
  15. char a;
  16. };
  17. class Base2
  18. {
  19. int b;
  20. };
  21. class Derived : public Base1, public Base2
  22. {
  23. long c;
  24. };
  25. class MostDerived : public Derived
  26. {
  27. char d[32];
  28. };
  29. template<class T>
  30. const boost::serialization::extended_type_info & eti(){
  31. return boost::serialization::singleton<
  32. boost::serialization::extended_type_info_typeid< T >
  33. >::get_const_instance();
  34. }
  35. int
  36. test_main( int /* argc */, char* /* argv */[] )
  37. {
  38. MostDerived md;
  39. MostDerived* pmd =& md;
  40. Derived* pd = static_cast<Derived*>(pmd);
  41. Base2* pb2 = static_cast<Base2*>(pmd);
  42. Base1* pb1 = static_cast<Base1*>(pd);
  43. void* vpmd = static_cast<void*>(pmd);
  44. void* vpb1 = static_cast<void*>(pb1);
  45. void* vpb2 = static_cast<void*>(pb2);
  46. void* vpd = static_cast<void*>(pd);
  47. // simple casts only requiring table lookup
  48. BOOST_CHECK(vpd == boost::serialization::void_downcast(
  49. eti<Derived>(),
  50. eti<Base1>(),
  51. vpb1
  52. ));
  53. BOOST_CHECK(vpb1 == boost::serialization::void_upcast(
  54. eti<Derived>(),
  55. eti<Base1>(),
  56. vpd
  57. ));
  58. BOOST_CHECK(vpd == boost::serialization::void_downcast(
  59. eti<Derived>(),
  60. eti<Base2>(),
  61. vpb2
  62. ));
  63. BOOST_CHECK(vpb2 == boost::serialization::void_upcast(
  64. eti<Derived>(),
  65. eti<Base2>(),
  66. vpd
  67. ));
  68. BOOST_CHECK(vpmd == boost::serialization::void_downcast(
  69. eti<MostDerived>(),
  70. eti<Derived>(),
  71. vpd
  72. ));
  73. BOOST_CHECK(vpd == boost::serialization::void_upcast(
  74. eti<MostDerived>(),
  75. eti<Derived>(),
  76. vpmd
  77. ));
  78. // note relationship between MostDerived and Base1 is automatically derived
  79. BOOST_CHECK(vpmd == boost::serialization::void_downcast(
  80. eti<MostDerived>(),
  81. eti<Base1>(),
  82. vpb1
  83. ));
  84. BOOST_CHECK(vpb1 == boost::serialization::void_upcast(
  85. eti<MostDerived>(),
  86. eti<Base1>(),
  87. vpmd
  88. ));
  89. // note relationship between MostDerived and Base2 is automatically derived
  90. BOOST_CHECK(vpmd == boost::serialization::void_downcast(
  91. eti<MostDerived>(),
  92. eti<Base2>(),
  93. vpb2
  94. ));
  95. BOOST_CHECK(vpb2 == boost::serialization::void_upcast(
  96. eti<MostDerived>(),
  97. eti<Base2>(),
  98. vpmd
  99. ));
  100. // note: currently derivations are not optimised. See void_cast.cpp
  101. // for and explanation. These should still work though.
  102. // need to double check to validate speed up optimization of derivations
  103. BOOST_CHECK(vpmd == boost::serialization::void_downcast(
  104. eti<MostDerived>(),
  105. eti<Base1>(),
  106. vpb1
  107. ));
  108. BOOST_CHECK(vpb1 == boost::serialization::void_upcast(
  109. eti<MostDerived>(),
  110. eti<Base1>(),
  111. vpmd
  112. ));
  113. BOOST_CHECK(vpmd == boost::serialization::void_downcast(
  114. eti<MostDerived>(),
  115. eti<Base2>(),
  116. vpb2
  117. ));
  118. BOOST_CHECK(vpb2 == boost::serialization::void_upcast(
  119. eti<MostDerived>(),
  120. eti<Base2>(),
  121. vpmd
  122. ));
  123. // check things that should fail
  124. BOOST_CHECK(NULL == boost::serialization::void_downcast(
  125. eti<Base2>(),
  126. eti<Base1>(),
  127. vpb1
  128. ));
  129. // note that a fundamental feature is that derived/base pairs are created
  130. // at compiler time so that all are registered before the main program starts
  131. // so leave the registration here at the end to verify this. Note bogus arguments
  132. // to workaround msvc 6 bug
  133. boost::serialization::void_cast_register<Derived, Base1>(
  134. static_cast<Derived *>(NULL),
  135. static_cast<Base1 *>(NULL)
  136. );
  137. boost::serialization::void_cast_register<Derived, Base2>(
  138. static_cast<Derived *>(NULL),
  139. static_cast<Base2 *>(NULL)
  140. );
  141. boost::serialization::void_cast_register<MostDerived, Derived>(
  142. static_cast<MostDerived *>(NULL),
  143. static_cast<Derived *>(NULL)
  144. );
  145. return EXIT_SUCCESS;
  146. }
  147. // EOF