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/serialization/split_free.hpp> |
25 | #include <boost/serialization/vector.hpp> |
26 | #include <string> |
27 | #include <vector> |
28 | |
29 | // this test uses a special string (my_string) whose contents are shared |
30 | // and hence saved in the archive only once. We need a helper in order |
31 | // to convert my_string into a serializable type |
32 | |
33 | class my_string:public std::string |
34 | { |
35 | typedef std::string super; |
36 | |
37 | public: |
38 | my_string(){} |
39 | my_string(const super & str): super(str){} |
40 | my_string & operator=(const super& rhs) { |
41 | super::operator=(str: rhs); |
42 | return *this; |
43 | } |
44 | }; |
45 | |
46 | struct my_string_helper |
47 | { |
48 | typedef std::vector<my_string> table; |
49 | table m_t; |
50 | }; |
51 | |
52 | BOOST_SERIALIZATION_SPLIT_FREE(my_string) |
53 | |
54 | namespace boost { |
55 | namespace serialization { |
56 | |
57 | template<class Archive> |
58 | void save(Archive & ar, const my_string & str, const unsigned int /* version */) |
59 | { |
60 | void (* const idx)(Archive &, const my_string &, const unsigned int) = & save; |
61 | void * const id = reinterpret_cast<void * const>(idx); |
62 | my_string_helper & msh = ar.template get_helper<my_string_helper>(id); |
63 | |
64 | my_string_helper::table t = msh.m_t; |
65 | my_string_helper::table::iterator it = std::find(first: t.begin(), last: t.end(), val: str); |
66 | if(it == t.end()){ |
67 | my_string_helper::table::size_type s = t.size(); |
68 | ar << make_nvp(n: "index" , v&: s); |
69 | t.push_back(x: str); |
70 | ar << make_nvp(n: "string" , v: static_cast<const std::string &>(str)); |
71 | } |
72 | else{ |
73 | my_string_helper::table::size_type s = it - t.begin(); |
74 | ar << make_nvp(n: "index" , v&: s); |
75 | } |
76 | } |
77 | |
78 | template<class Archive> |
79 | void load(Archive & ar, my_string & str, const unsigned int /* version */) |
80 | { |
81 | void (* const idx)(Archive &, my_string &, const unsigned int) = & load; |
82 | void * const id = reinterpret_cast<void * const>(idx); |
83 | my_string_helper & msh = ar.template get_helper<my_string_helper>(id); |
84 | |
85 | my_string_helper::table t = msh.m_t; |
86 | |
87 | my_string_helper::table::size_type s; |
88 | ar >> make_nvp(n: "index" , v&: s); |
89 | t.reserve(n: s); |
90 | if(s >= t.size()){ |
91 | std::string tmp; |
92 | ar >> make_nvp(n: "string" , v&: tmp); |
93 | str = tmp; |
94 | t.push_back(x: str); |
95 | } |
96 | else{ |
97 | str = t[s]; |
98 | } |
99 | } |
100 | |
101 | } // namespace serialization |
102 | } // namespace boost |
103 | |
104 | int test_main( int /* argc */, char* /* argv */[] ){ |
105 | const char * testfile = boost::archive::tmpnam(NULL); |
106 | BOOST_REQUIRE(NULL != testfile); |
107 | |
108 | std::vector<my_string> v1; |
109 | for(int i=0; i<1000; ++i){ |
110 | char sbuffer[10]; |
111 | std::snprintf(s: sbuffer, maxlen: sizeof(sbuffer), format: "%i" , i % 100); |
112 | v1.push_back(x: my_string(sbuffer)); |
113 | } |
114 | { |
115 | test_ostream os(testfile, TEST_STREAM_FLAGS); |
116 | test_oarchive oa(os, TEST_ARCHIVE_FLAGS); |
117 | oa << boost::serialization::make_nvp(n: "vector" , v&: v1); |
118 | } |
119 | { |
120 | std::vector<my_string> v2; |
121 | test_istream is(testfile, TEST_STREAM_FLAGS); |
122 | test_iarchive ia(is, TEST_ARCHIVE_FLAGS); |
123 | ia >> boost::serialization::make_nvp(n: "vector" , v&: v2); |
124 | BOOST_CHECK(v1 == v2); |
125 | } |
126 | std::remove(filename: testfile); |
127 | return EXIT_SUCCESS; |
128 | } |
129 | |
130 | // EOF |
131 | |