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