• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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