1 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 2 // test_polymorphic.cpp 3 4 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 5 // Use, modification and distribution is subject to the Boost Software 6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 // should pass compilation and execution 10 11 #include <cstddef> // NULL 12 #include <cstdio> // remove 13 #include <fstream> 14 15 #include <boost/config.hpp> 16 #if defined(BOOST_NO_STDC_NAMESPACE) 17 namespace std{ 18 using ::remove; 19 } 20 #endif 21 22 // the following is to ensure that when one of the libraries changes 23 // BJAM rebuilds and relinks the test. 24 /* 25 #include "polymorphic_text_archive.hpp" 26 #include "polymorphic_text_warchive.hpp" 27 #include "polymorphic_binary_archive.hpp" 28 #include "polymorphic_xml_archive.hpp" 29 #include "polymorphic_xml_warchive.hpp" 30 */ 31 32 #include <string> 33 #include <vector> 34 35 #include "test_tools.hpp" 36 #include <boost/lexical_cast.hpp> 37 #include <boost/serialization/split_free.hpp> 38 #include <boost/serialization/vector.hpp> 39 #include <boost/serialization/nvp.hpp> 40 // this test uses a special string (my_string) whose contents are shared 41 // and hence saved in the archive only once. We need a helper in order 42 // to convert my_string into a serializable type 43 44 class my_string:public std::string 45 { 46 typedef std::string super; 47 48 public: my_string()49 my_string(){} my_string(const super & str)50 my_string(const super & str): super(str){} operator =(const super & rhs)51 my_string & operator=(const super& rhs) { 52 super::operator=(rhs); 53 return *this; 54 } 55 }; 56 57 struct my_string_helper 58 { 59 typedef std::vector<my_string> table; 60 table m_t; 61 }; 62 63 BOOST_SERIALIZATION_SPLIT_FREE(my_string) 64 65 namespace boost { 66 namespace serialization { 67 68 template<class Archive> save(Archive & ar,const my_string & str,const unsigned int)69 void save(Archive & ar, const my_string & str, const unsigned int /* version */) 70 { 71 void (* const idx)(Archive &, const my_string &, const unsigned int) = & save; 72 void * const id = reinterpret_cast<void * const>(idx); 73 my_string_helper & msh = ar.template get_helper<my_string_helper>(id); 74 75 my_string_helper::table t = msh.m_t; 76 my_string_helper::table::iterator it = std::find(t.begin(), t.end(), str); 77 if(it == t.end()){ 78 my_string_helper::table::size_type s = t.size(); 79 ar << make_nvp("index", s); 80 t.push_back(str); 81 ar << make_nvp("string", static_cast<const std::string &>(str)); 82 } 83 else{ 84 my_string_helper::table::size_type s = it - t.begin(); 85 ar << make_nvp("index", s); 86 } 87 } 88 89 template<class Archive> load(Archive & ar,my_string & str,const unsigned int)90 void load(Archive & ar, my_string & str, const unsigned int /* version */) 91 { 92 void (* const idx)(Archive &, my_string &, const unsigned int) = & load; 93 void * const id = reinterpret_cast<void * const>(idx); 94 my_string_helper & msh = ar.template get_helper<my_string_helper>(id); 95 96 my_string_helper::table t = msh.m_t; 97 98 my_string_helper::table::size_type s; 99 ar >> make_nvp("index", s); 100 t.reserve(s); 101 if(s >= t.size()){ 102 std::string tmp; 103 ar >> make_nvp("string", tmp); 104 str = tmp; 105 t.push_back(str); 106 } 107 else{ 108 str = t[s]; 109 } 110 } 111 112 } // namespace serialization 113 } // namespace boost 114 #include <boost/archive/polymorphic_oarchive.hpp> 115 #include <boost/archive/polymorphic_iarchive.hpp> 116 test_main(int,char * [])117 int test_main(int /* argc */, char * /* argv */ []) 118 { 119 const char * testfile = boost::archive::tmpnam(NULL); 120 BOOST_REQUIRE(NULL != testfile); 121 122 std::vector<my_string> v1; 123 for(int i=0; i<1000; ++i){ 124 v1.push_back(my_string(boost::lexical_cast<std::string>(i % 100))); 125 } 126 127 // test using using polymorphic implementation. 128 { 129 test_ostream os(testfile, TEST_STREAM_FLAGS); 130 test_oarchive oa_implementation(os, TEST_ARCHIVE_FLAGS); 131 oa_implementation << boost::serialization::make_nvp("vector", v1); 132 } 133 { 134 std::vector<my_string> v2; 135 test_istream is(testfile, TEST_STREAM_FLAGS); 136 test_iarchive ia_implementation(is, TEST_ARCHIVE_FLAGS); 137 ia_implementation >> boost::serialization::make_nvp("vector", v2); 138 BOOST_CHECK(v1 == v2); 139 } 140 std::remove(testfile); 141 142 // test using using polymorphic interface. 143 { 144 test_ostream os(testfile, TEST_STREAM_FLAGS); 145 test_oarchive oa_implementation(os, TEST_ARCHIVE_FLAGS); 146 boost::archive::polymorphic_oarchive & oa_interface = oa_implementation; 147 oa_interface << boost::serialization::make_nvp("vector", v1); 148 } 149 { 150 std::vector<my_string> v2; 151 test_istream is(testfile, TEST_STREAM_FLAGS); 152 test_iarchive ia_implementation(is, TEST_ARCHIVE_FLAGS); 153 boost::archive::polymorphic_iarchive & ia_interface = ia_implementation; 154 ia_interface >> boost::serialization::make_nvp("vector", v2); 155 BOOST_CHECK(v1 == v2); 156 } 157 std::remove(testfile); 158 std::remove(testfile); 159 return EXIT_SUCCESS; 160 } 161