test_p_helper.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_polymorphic.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. // the following is to ensure that when one of the libraries changes
  18. // BJAM rebuilds and relinks the test.
  19. /*
  20. #include "polymorphic_text_archive.hpp"
  21. #include "polymorphic_text_warchive.hpp"
  22. #include "polymorphic_binary_archive.hpp"
  23. #include "polymorphic_xml_archive.hpp"
  24. #include "polymorphic_xml_warchive.hpp"
  25. */
  26. #include <string>
  27. #include <vector>
  28. #include "test_tools.hpp"
  29. #include <boost/lexical_cast.hpp>
  30. #include <boost/serialization/split_free.hpp>
  31. #include <boost/serialization/vector.hpp>
  32. #include <boost/serialization/nvp.hpp>
  33. // this test uses a special string (my_string) whose contents are shared
  34. // and hence saved in the archive only once. We need a helper in order
  35. // to convert my_string into a serializable type
  36. class my_string:public std::string
  37. {
  38. typedef std::string super;
  39. public:
  40. my_string(){}
  41. my_string(const super & str): super(str){}
  42. my_string & operator=(const super& rhs) {
  43. super::operator=(rhs);
  44. return *this;
  45. }
  46. };
  47. struct my_string_helper
  48. {
  49. typedef std::vector<my_string> table;
  50. table m_t;
  51. };
  52. BOOST_SERIALIZATION_SPLIT_FREE(my_string)
  53. namespace boost {
  54. namespace serialization {
  55. template<class Archive>
  56. void save(Archive & ar, const my_string & str, const unsigned int /* version */)
  57. {
  58. void (* const idx)(Archive &, const my_string &, const unsigned int) = & save;
  59. void * const id = reinterpret_cast<void * const>(idx);
  60. my_string_helper & msh = ar.template get_helper<my_string_helper>(id);
  61. my_string_helper::table t = msh.m_t;
  62. my_string_helper::table::iterator it = std::find(t.begin(), t.end(), str);
  63. if(it == t.end()){
  64. my_string_helper::table::size_type s = t.size();
  65. ar << make_nvp("index", s);
  66. t.push_back(str);
  67. ar << make_nvp("string", static_cast<const std::string &>(str));
  68. }
  69. else{
  70. my_string_helper::table::size_type s = it - t.begin();
  71. ar << make_nvp("index", s);
  72. }
  73. }
  74. template<class Archive>
  75. void load(Archive & ar, my_string & str, const unsigned int /* version */)
  76. {
  77. void (* const idx)(Archive &, my_string &, const unsigned int) = & load;
  78. void * const id = reinterpret_cast<void * const>(idx);
  79. my_string_helper & msh = ar.template get_helper<my_string_helper>(id);
  80. my_string_helper::table t = msh.m_t;
  81. my_string_helper::table::size_type s;
  82. ar >> make_nvp("index", s);
  83. t.reserve(s);
  84. if(s >= t.size()){
  85. std::string tmp;
  86. ar >> make_nvp("string", tmp);
  87. str = tmp;
  88. t.push_back(str);
  89. }
  90. else{
  91. str = t[s];
  92. }
  93. }
  94. } // namespace serialization
  95. } // namespace boost
  96. #include <boost/archive/polymorphic_oarchive.hpp>
  97. #include <boost/archive/polymorphic_iarchive.hpp>
  98. int test_main(int /* argc */, char * /* argv */ [])
  99. {
  100. const char * testfile = boost::archive::tmpnam(NULL);
  101. BOOST_REQUIRE(NULL != testfile);
  102. std::vector<my_string> v1;
  103. for(int i=0; i<1000; ++i){
  104. v1.push_back(my_string(boost::lexical_cast<std::string>(i % 100)));
  105. }
  106. // test using using polymorphic implementation.
  107. {
  108. test_ostream os(testfile, TEST_STREAM_FLAGS);
  109. test_oarchive oa_implementation(os, TEST_ARCHIVE_FLAGS);
  110. oa_implementation << boost::serialization::make_nvp("vector", v1);
  111. }
  112. {
  113. std::vector<my_string> v2;
  114. test_istream is(testfile, TEST_STREAM_FLAGS);
  115. test_iarchive ia_implementation(is, TEST_ARCHIVE_FLAGS);
  116. ia_implementation >> boost::serialization::make_nvp("vector", v2);
  117. BOOST_CHECK(v1 == v2);
  118. }
  119. std::remove(testfile);
  120. // test using using polymorphic interface.
  121. {
  122. test_ostream os(testfile, TEST_STREAM_FLAGS);
  123. test_oarchive oa_implementation(os, TEST_ARCHIVE_FLAGS);
  124. boost::archive::polymorphic_oarchive & oa_interface = oa_implementation;
  125. oa_interface << boost::serialization::make_nvp("vector", v1);
  126. }
  127. {
  128. std::vector<my_string> v2;
  129. test_istream is(testfile, TEST_STREAM_FLAGS);
  130. test_iarchive ia_implementation(is, TEST_ARCHIVE_FLAGS);
  131. boost::archive::polymorphic_iarchive & ia_interface = ia_implementation;
  132. ia_interface >> boost::serialization::make_nvp("vector", v2);
  133. BOOST_CHECK(v1 == v2);
  134. }
  135. std::remove(testfile);
  136. std::remove(testfile);
  137. return EXIT_SUCCESS;
  138. }