1 | /* Boost.MultiIndex test for serialization. |
---|
2 | * |
---|
3 | * Copyright 2003-2005 Joaquín M López Muñoz. |
---|
4 | * Distributed under the Boost Software License, Version 1.0. |
---|
5 | * (See accompanying file LICENSE_1_0.txt or copy at |
---|
6 | * http://www.boost.org/LICENSE_1_0.txt) |
---|
7 | * |
---|
8 | * See http://www.boost.org/libs/multi_index for library home page. |
---|
9 | */ |
---|
10 | |
---|
11 | #include "test_serialization.hpp" |
---|
12 | |
---|
13 | #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ |
---|
14 | #include <boost/archive/text_oarchive.hpp> |
---|
15 | #include <boost/archive/text_iarchive.hpp> |
---|
16 | #include "pre_multi_index.hpp" |
---|
17 | #include <boost/multi_index_container.hpp> |
---|
18 | #include <boost/multi_index/hashed_index.hpp> |
---|
19 | #include <boost/multi_index/ordered_index.hpp> |
---|
20 | #include <boost/multi_index/sequenced_index.hpp> |
---|
21 | #include <boost/multi_index/key_extractors.hpp> |
---|
22 | #include <boost/noncopyable.hpp> |
---|
23 | #include <boost/test/test_tools.hpp> |
---|
24 | #include <sstream> |
---|
25 | #include <string> |
---|
26 | #include <vector> |
---|
27 | #include "pair_of_ints.hpp" |
---|
28 | |
---|
29 | using namespace boost::multi_index; |
---|
30 | |
---|
31 | template<int N> |
---|
32 | struct all_indices_equal_helper |
---|
33 | { |
---|
34 | template<class MultiIndexContainer> |
---|
35 | static bool compare( |
---|
36 | const MultiIndexContainer& m1,const MultiIndexContainer& m2) |
---|
37 | { |
---|
38 | if(!(get<N>(m1)==get<N>(m2))){ |
---|
39 | return false; |
---|
40 | } |
---|
41 | return all_indices_equal_helper<N-1>::compare(m1,m2); |
---|
42 | } |
---|
43 | }; |
---|
44 | |
---|
45 | template<> |
---|
46 | struct all_indices_equal_helper<0> |
---|
47 | { |
---|
48 | template<class MultiIndexContainer> |
---|
49 | static bool compare( |
---|
50 | const MultiIndexContainer& m1,const MultiIndexContainer& m2) |
---|
51 | { |
---|
52 | return true; |
---|
53 | } |
---|
54 | }; |
---|
55 | |
---|
56 | template<class MultiIndexContainer> |
---|
57 | bool all_indices_equal( |
---|
58 | const MultiIndexContainer& m1,const MultiIndexContainer& m2) |
---|
59 | { |
---|
60 | BOOST_STATIC_CONSTANT(int, |
---|
61 | N=boost::mpl::size< |
---|
62 | BOOST_DEDUCED_TYPENAME MultiIndexContainer::index_type_list>::type::value); |
---|
63 | |
---|
64 | return all_indices_equal_helper<N-1>::compare(m1,m2); |
---|
65 | } |
---|
66 | |
---|
67 | template<class MultiIndexContainer> |
---|
68 | void test_serialization(const MultiIndexContainer& m) |
---|
69 | { |
---|
70 | typedef typename MultiIndexContainer::iterator iterator; |
---|
71 | typedef typename MultiIndexContainer::const_iterator const_iterator; |
---|
72 | |
---|
73 | std::ostringstream oss; |
---|
74 | { |
---|
75 | boost::archive::text_oarchive oa(oss); |
---|
76 | oa<<m; |
---|
77 | |
---|
78 | std::vector<const_iterator> its(m.size()); |
---|
79 | const_iterator it_end=m.end(); |
---|
80 | for(const_iterator it=m.begin();it!=it_end;++it){ |
---|
81 | its.push_back(it); |
---|
82 | oa<<const_cast<const const_iterator&>(its.back()); |
---|
83 | } |
---|
84 | oa<<const_cast<const const_iterator&>(it_end); |
---|
85 | } |
---|
86 | |
---|
87 | MultiIndexContainer m2; |
---|
88 | std::istringstream iss(oss.str()); |
---|
89 | boost::archive::text_iarchive ia(iss); |
---|
90 | ia>>m2; |
---|
91 | BOOST_CHECK(all_indices_equal(m,m2)); |
---|
92 | |
---|
93 | iterator it_end=m2.end(); |
---|
94 | for(iterator it=m2.begin();it!=it_end;++it){ |
---|
95 | iterator it2; |
---|
96 | ia>>it2; |
---|
97 | BOOST_CHECK(it==it2); |
---|
98 | |
---|
99 | /* exercise safe mode with this (unchecked) iterator */ |
---|
100 | BOOST_CHECK(*it==*it2); |
---|
101 | m2.erase(it,it2); |
---|
102 | m2.erase(it2,it2); |
---|
103 | m2.erase(it2,it); |
---|
104 | iterator it3(++it2); |
---|
105 | iterator it4; |
---|
106 | it4=--it2; |
---|
107 | BOOST_CHECK(it==it4); |
---|
108 | BOOST_CHECK(it==project<0>(m2,it4)); |
---|
109 | } |
---|
110 | iterator it2; |
---|
111 | ia>>it2; |
---|
112 | BOOST_CHECK(it_end==it2); |
---|
113 | BOOST_CHECK(it_end==project<0>(m2,it2)); |
---|
114 | } |
---|
115 | |
---|
116 | void test_hashed_index_serialization() |
---|
117 | { |
---|
118 | const int N=100; |
---|
119 | const int SHUFFLE=10232; |
---|
120 | |
---|
121 | typedef multi_index_container< |
---|
122 | int, |
---|
123 | indexed_by< |
---|
124 | hashed_unique<identity<int> >, |
---|
125 | sequenced<> |
---|
126 | > |
---|
127 | > hashed_set; |
---|
128 | |
---|
129 | typedef hashed_set::iterator iterator; |
---|
130 | typedef hashed_set::local_iterator local_iterator; |
---|
131 | |
---|
132 | hashed_set hs; |
---|
133 | |
---|
134 | for(int i=0;i<N;++i){ |
---|
135 | hs.insert(i*SHUFFLE); |
---|
136 | } |
---|
137 | |
---|
138 | std::ostringstream oss; |
---|
139 | { |
---|
140 | boost::archive::text_oarchive oa(oss); |
---|
141 | oa<<const_cast<const hashed_set&>(hs); |
---|
142 | |
---|
143 | std::vector<iterator> its(N); |
---|
144 | for(int i=0;i<N;++i){ |
---|
145 | iterator it=hs.find(i*SHUFFLE); |
---|
146 | its.push_back(it); |
---|
147 | oa<<const_cast<const iterator&>(its.back()); |
---|
148 | } |
---|
149 | iterator it=hs.end(); |
---|
150 | oa<<const_cast<const iterator&>(it); |
---|
151 | |
---|
152 | std::vector<local_iterator> lits(2*N); |
---|
153 | for(std::size_t buc=0;buc<hs.bucket_count();++buc){ |
---|
154 | for(local_iterator lit=hs.begin(buc),lit_end=hs.end(buc); |
---|
155 | lit!=lit_end;++lit){ |
---|
156 | oa<<*lit; |
---|
157 | lits.push_back(lit); |
---|
158 | oa<<const_cast<const local_iterator&>(lits.back()); |
---|
159 | } |
---|
160 | local_iterator lit2=hs.end(buc); |
---|
161 | lits.push_back(lit2); |
---|
162 | oa<<const_cast<const local_iterator&>(lits.back()); |
---|
163 | } |
---|
164 | } |
---|
165 | |
---|
166 | hashed_set hs2; |
---|
167 | std::istringstream iss(oss.str()); |
---|
168 | boost::archive::text_iarchive ia(iss); |
---|
169 | ia>>hs2; |
---|
170 | BOOST_CHECK(get<1>(hs)==get<1>(hs2)); |
---|
171 | |
---|
172 | for(int j=0;j<N;++j){ |
---|
173 | iterator it; |
---|
174 | ia>>it; |
---|
175 | BOOST_CHECK(*it==j*SHUFFLE); |
---|
176 | } |
---|
177 | iterator it; |
---|
178 | ia>>it; |
---|
179 | BOOST_CHECK(it==hs2.end()); |
---|
180 | |
---|
181 | for(std::size_t buc=0;buc<hs2.bucket_count();++buc){ |
---|
182 | for(std::size_t k=0;k<hs2.bucket_size(buc);++k){ |
---|
183 | int n; |
---|
184 | local_iterator it; |
---|
185 | ia>>n; |
---|
186 | ia>>it; |
---|
187 | BOOST_CHECK(*it==n); |
---|
188 | } |
---|
189 | local_iterator it2; |
---|
190 | ia>>it2; |
---|
191 | BOOST_CHECK(it2==hs2.end(buc)); |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | void test_serialization() |
---|
196 | { |
---|
197 | { |
---|
198 | typedef multi_index_container< |
---|
199 | int, |
---|
200 | indexed_by< |
---|
201 | sequenced<>, |
---|
202 | sequenced<> |
---|
203 | > |
---|
204 | > multi_index_t; |
---|
205 | |
---|
206 | multi_index_t m; |
---|
207 | for(int i=0;i<100;++i)m.push_back(i); |
---|
208 | m.reverse(); |
---|
209 | test_serialization(m); |
---|
210 | |
---|
211 | m.clear(); |
---|
212 | for(int j=50;j<100;++j)m.push_back(j); |
---|
213 | for(int k=0;k<50;++k)m.push_back(k); |
---|
214 | m.sort(); |
---|
215 | test_serialization(m); |
---|
216 | } |
---|
217 | { |
---|
218 | typedef multi_index_container< |
---|
219 | int, |
---|
220 | indexed_by< |
---|
221 | sequenced<>, |
---|
222 | ordered_non_unique<identity<int> > |
---|
223 | > |
---|
224 | > multi_index_t; |
---|
225 | |
---|
226 | multi_index_t m; |
---|
227 | for(int i=0;i<100;++i){ |
---|
228 | m.push_back(i); |
---|
229 | m.push_back(i); |
---|
230 | m.push_back(i); |
---|
231 | } |
---|
232 | m.reverse(); |
---|
233 | test_serialization(m); |
---|
234 | } |
---|
235 | { |
---|
236 | typedef multi_index_container< |
---|
237 | pair_of_ints, |
---|
238 | indexed_by< |
---|
239 | ordered_unique< |
---|
240 | BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first) |
---|
241 | >, |
---|
242 | ordered_non_unique< |
---|
243 | BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second) |
---|
244 | >, |
---|
245 | sequenced<> |
---|
246 | > |
---|
247 | > multi_index_t; |
---|
248 | |
---|
249 | multi_index_t m; |
---|
250 | test_serialization(m); |
---|
251 | |
---|
252 | m.insert(pair_of_ints(4,0)); |
---|
253 | test_serialization(m); |
---|
254 | |
---|
255 | m.insert(pair_of_ints(3,1)); |
---|
256 | m.insert(pair_of_ints(2,1)); |
---|
257 | test_serialization(m); |
---|
258 | |
---|
259 | m.insert(pair_of_ints(1,1)); |
---|
260 | test_serialization(m); |
---|
261 | |
---|
262 | m.insert(pair_of_ints(0,0)); |
---|
263 | test_serialization(m); |
---|
264 | |
---|
265 | m.insert(pair_of_ints(5,1)); |
---|
266 | m.insert(pair_of_ints(7,1)); |
---|
267 | m.insert(pair_of_ints(6,1)); |
---|
268 | test_serialization(m); |
---|
269 | |
---|
270 | m.insert(pair_of_ints(8,1)); |
---|
271 | m.insert(pair_of_ints(9,1)); |
---|
272 | m.insert(pair_of_ints(12,1)); |
---|
273 | m.insert(pair_of_ints(11,1)); |
---|
274 | m.insert(pair_of_ints(10,1)); |
---|
275 | test_serialization(m); |
---|
276 | } |
---|
277 | test_hashed_index_serialization(); |
---|
278 | } |
---|