test_registered.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_registered.cpp
  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. // should pass compilation and execution
  8. #include <cstddef> // NULL
  9. #include <cstdio> // remove
  10. #include <fstream>
  11. #include <boost/config.hpp>
  12. #if defined(BOOST_NO_STDC_NAMESPACE)
  13. namespace std{
  14. using ::remove;
  15. }
  16. #endif
  17. #include <boost/archive/archive_exception.hpp>
  18. #include "test_tools.hpp"
  19. #include <boost/serialization/base_object.hpp>
  20. #include <boost/serialization/type_info_implementation.hpp>
  21. class polymorphic_base
  22. {
  23. friend class boost::serialization::access;
  24. template<class Archive>
  25. void serialize(Archive & /* ar */, const unsigned int /* file_version */){
  26. }
  27. public:
  28. virtual ~polymorphic_base(){};
  29. };
  30. class polymorphic_derived1 : public polymorphic_base
  31. {
  32. friend class boost::serialization::access;
  33. template<class Archive>
  34. void serialize(Archive &ar, const unsigned int /* file_version */){
  35. ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
  36. }
  37. };
  38. class polymorphic_derived2 : public polymorphic_base
  39. {
  40. friend class boost::serialization::access;
  41. template<class Archive>
  42. void serialize(Archive &ar, const unsigned int /* file_version */){
  43. ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
  44. }
  45. };
  46. // save derived polymorphic class
  47. void save_derived(const char *testfile)
  48. {
  49. test_ostream os(testfile, TEST_STREAM_FLAGS);
  50. test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
  51. polymorphic_derived1 *rd1 = new polymorphic_derived1;
  52. polymorphic_derived2 *rd2 = new polymorphic_derived2;
  53. // registration IS necessary when serializing pointers of
  54. // polymorphic classes
  55. oa.register_type(static_cast<polymorphic_derived1 *>(NULL));
  56. oa.register_type(static_cast<polymorphic_derived2 *>(NULL));
  57. oa << BOOST_SERIALIZATION_NVP(rd1);
  58. oa << BOOST_SERIALIZATION_NVP(rd2);
  59. // the above opereration registers the derived classes as a side
  60. // effect. Hence, instances can now be correctly serialized through
  61. // a base class pointer.
  62. polymorphic_base *rb1 = rd1;
  63. polymorphic_base *rb2 = rd2;
  64. oa << BOOST_SERIALIZATION_NVP(rb1);
  65. oa << BOOST_SERIALIZATION_NVP(rb2);
  66. delete rd1;
  67. delete rd2;
  68. }
  69. // save derived polymorphic class
  70. void load_derived(const char *testfile)
  71. {
  72. test_istream is(testfile, TEST_STREAM_FLAGS);
  73. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  74. polymorphic_derived1 *rd1 = NULL;
  75. polymorphic_derived2 *rd2 = NULL;
  76. // registration IS necessary when serializing pointers of
  77. // polymorphic classes
  78. ia.register_type(static_cast<polymorphic_derived1 *>(NULL));
  79. ia.register_type(static_cast<polymorphic_derived2 *>(NULL));
  80. ia >> BOOST_SERIALIZATION_NVP(rd1);
  81. const boost::serialization::extended_type_info * p1;
  82. p1 = & boost::serialization::type_info_implementation<polymorphic_derived1>
  83. ::type::get_const_instance();
  84. BOOST_CHECK(NULL != p1);
  85. const boost::serialization::extended_type_info * p2;
  86. p2 = boost::serialization::type_info_implementation<polymorphic_derived1>
  87. ::type::get_const_instance().get_derived_extended_type_info(*rd1);
  88. BOOST_CHECK(NULL != p2);
  89. BOOST_CHECK_MESSAGE(p1 == p2, "restored pointer d1 not of correct type");
  90. ia >> BOOST_SERIALIZATION_NVP(rd2);
  91. BOOST_CHECK_MESSAGE(
  92. & boost::serialization::type_info_implementation<polymorphic_derived2>
  93. ::type::get_const_instance()
  94. ==
  95. boost::serialization::type_info_implementation<polymorphic_derived2>
  96. ::type::get_const_instance().get_derived_extended_type_info(*rd2),
  97. "restored pointer d2 not of correct type"
  98. );
  99. polymorphic_base *rb1 = NULL;
  100. polymorphic_base *rb2 = NULL;
  101. // the above opereration registers the derived classes as a side
  102. // effect. Hence, instances can now be correctly serialized through
  103. // a base class pointer.
  104. ia >> BOOST_SERIALIZATION_NVP(rb1);
  105. BOOST_CHECK_MESSAGE(
  106. rb1 == dynamic_cast<polymorphic_base *>(rd1),
  107. "serialized pointers not correctly restored"
  108. );
  109. p1 = & boost::serialization::type_info_implementation<polymorphic_derived1>
  110. ::type::get_const_instance();
  111. BOOST_CHECK(NULL != p1);
  112. p2 = boost::serialization::type_info_implementation<polymorphic_base>
  113. ::type::get_const_instance().get_derived_extended_type_info(*rb1);
  114. BOOST_CHECK(NULL != p2);
  115. BOOST_CHECK_MESSAGE(p1 == p2, "restored pointer b1 not of correct type");
  116. ia >> BOOST_SERIALIZATION_NVP(rb2);
  117. BOOST_CHECK_MESSAGE(
  118. rb2 == dynamic_cast<polymorphic_base *>(rd2),
  119. "serialized pointers not correctly restored"
  120. );
  121. BOOST_CHECK_MESSAGE(
  122. & boost::serialization::type_info_implementation<polymorphic_derived2>
  123. ::type::get_const_instance()
  124. == boost::serialization::type_info_implementation<polymorphic_base>
  125. ::type::get_const_instance().get_derived_extended_type_info(*rb2),
  126. "restored pointer b2 not of correct type"
  127. );
  128. delete rb1;
  129. delete rb2;
  130. }
  131. // save registered polymorphic class
  132. void save_registered(const char *testfile)
  133. {
  134. test_ostream os(testfile, TEST_STREAM_FLAGS);
  135. test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
  136. polymorphic_base *rb1 = new polymorphic_derived1;
  137. polymorphic_base *rb2 = new polymorphic_derived2;
  138. // registration (forward declaration) will permit correct serialization
  139. // through a pointer to a base class
  140. oa.register_type(static_cast<polymorphic_derived1 *>(NULL));
  141. oa.register_type(static_cast<polymorphic_derived2 *>(NULL));
  142. oa << BOOST_SERIALIZATION_NVP(rb1) << BOOST_SERIALIZATION_NVP(rb2);
  143. delete rb1;
  144. delete rb2;
  145. }
  146. // save registered polymorphic class
  147. void load_registered(const char *testfile)
  148. {
  149. test_istream is(testfile, TEST_STREAM_FLAGS);
  150. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  151. polymorphic_base *rb1 = NULL;
  152. polymorphic_base *rb2 = NULL;
  153. // registration (forward declaration) will permit correct serialization
  154. // through a pointer to a base class
  155. ia.register_type(static_cast<polymorphic_derived1 *>(NULL));
  156. ia.register_type(static_cast<polymorphic_derived2 *>(NULL));
  157. ia >> BOOST_SERIALIZATION_NVP(rb1) >> BOOST_SERIALIZATION_NVP(rb2);
  158. BOOST_CHECK_MESSAGE(
  159. & boost::serialization::type_info_implementation<polymorphic_derived1>
  160. ::type::get_const_instance()
  161. == boost::serialization::type_info_implementation<polymorphic_base>
  162. ::type::get_const_instance().get_derived_extended_type_info(*rb1),
  163. "restored pointer b1 not of correct type"
  164. );
  165. BOOST_CHECK_MESSAGE(
  166. & boost::serialization::type_info_implementation<polymorphic_derived2>
  167. ::type::get_const_instance()
  168. == boost::serialization::type_info_implementation<polymorphic_base>
  169. ::type::get_const_instance().get_derived_extended_type_info(*rb2),
  170. "restored pointer b2 not of correct type"
  171. );
  172. delete rb1;
  173. delete rb2;
  174. }
  175. int
  176. test_main( int /* argc */, char* /* argv */[] )
  177. {
  178. const char * testfile = boost::archive::tmpnam(NULL);
  179. BOOST_REQUIRE(NULL != testfile);
  180. save_derived(testfile);
  181. load_derived(testfile);
  182. save_registered(testfile);
  183. load_registered(testfile);
  184. std::remove(testfile);
  185. return EXIT_SUCCESS;
  186. }
  187. // EOF