test_helper_support.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_helper_support.cpp
  3. // (C) Copyright 2008 Joaquin M Lopez Munoz.
  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 <algorithm>
  9. #include <cstddef>
  10. #include <fstream>
  11. #include <cstdio> // remove
  12. #include <boost/config.hpp>
  13. #if defined(BOOST_NO_STDC_NAMESPACE)
  14. namespace std{
  15. using ::remove;
  16. }
  17. #endif
  18. #include "test_tools.hpp"
  19. #include <boost/lexical_cast.hpp>
  20. #include <boost/serialization/split_free.hpp>
  21. #include <boost/serialization/vector.hpp>
  22. #include <string>
  23. #include <vector>
  24. // this test uses a special string (my_string) whose contents are shared
  25. // and hence saved in the archive only once. We need a helper in order
  26. // to convert my_string into a serializable type
  27. class my_string:public std::string
  28. {
  29. typedef std::string super;
  30. public:
  31. my_string(){}
  32. my_string(const super & str): super(str){}
  33. my_string & operator=(const super& rhs) {
  34. super::operator=(rhs);
  35. return *this;
  36. }
  37. };
  38. struct my_string_helper
  39. {
  40. typedef std::vector<my_string> table;
  41. table m_t;
  42. };
  43. BOOST_SERIALIZATION_SPLIT_FREE(my_string)
  44. namespace boost {
  45. namespace serialization {
  46. template<class Archive>
  47. void save(Archive & ar, const my_string & str, const unsigned int /* version */)
  48. {
  49. void (* const idx)(Archive &, const my_string &, const unsigned int) = & save;
  50. void * const id = reinterpret_cast<void * const>(idx);
  51. my_string_helper & msh = ar.template get_helper<my_string_helper>(id);
  52. my_string_helper::table t = msh.m_t;
  53. my_string_helper::table::iterator it = std::find(t.begin(), t.end(), str);
  54. if(it == t.end()){
  55. my_string_helper::table::size_type s = t.size();
  56. ar << make_nvp("index", s);
  57. t.push_back(str);
  58. ar << make_nvp("string", static_cast<const std::string &>(str));
  59. }
  60. else{
  61. my_string_helper::table::size_type s = it - t.begin();
  62. ar << make_nvp("index", s);
  63. }
  64. }
  65. template<class Archive>
  66. void load(Archive & ar, my_string & str, const unsigned int /* version */)
  67. {
  68. void (* const idx)(Archive &, my_string &, const unsigned int) = & load;
  69. void * const id = reinterpret_cast<void * const>(idx);
  70. my_string_helper & msh = ar.template get_helper<my_string_helper>(id);
  71. my_string_helper::table t = msh.m_t;
  72. my_string_helper::table::size_type s;
  73. ar >> make_nvp("index", s);
  74. t.reserve(s);
  75. if(s >= t.size()){
  76. std::string tmp;
  77. ar >> make_nvp("string", tmp);
  78. str = tmp;
  79. t.push_back(str);
  80. }
  81. else{
  82. str = t[s];
  83. }
  84. }
  85. } // namespace serialization
  86. } // namespace boost
  87. int test_main( int /* argc */, char* /* argv */[] ){
  88. const char * testfile = boost::archive::tmpnam(NULL);
  89. BOOST_REQUIRE(NULL != testfile);
  90. std::vector<my_string> v1;
  91. for(int i=0; i<1000; ++i){
  92. v1.push_back(my_string(boost::lexical_cast<std::string>(i % 100)));
  93. }
  94. {
  95. test_ostream os(testfile, TEST_STREAM_FLAGS);
  96. test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
  97. oa << boost::serialization::make_nvp("vector", v1);
  98. }
  99. {
  100. std::vector<my_string> v2;
  101. test_istream is(testfile, TEST_STREAM_FLAGS);
  102. test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
  103. ia >> boost::serialization::make_nvp("vector", v2);
  104. BOOST_CHECK(v1 == v2);
  105. }
  106. std::remove(testfile);
  107. return EXIT_SUCCESS;
  108. }
  109. // EOF