]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multi_index/test/test_safe_mode.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / multi_index / test / test_safe_mode.cpp
1 /* Boost.MultiIndex test for safe_mode.
2 *
3 * Copyright 2003-2015 Joaquin M Lopez Munoz.
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_safe_mode.hpp"
12
13 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
14 #include "pre_multi_index.hpp"
15 #include "employee.hpp"
16 #include "pair_of_ints.hpp"
17 #include <stdexcept>
18 #include <boost/detail/lightweight_test.hpp>
19
20 using namespace boost::multi_index;
21
22 #define TRY_SAFE_MODE \
23 try{
24
25 #define CATCH_SAFE_MODE(err) \
26 throw std::runtime_error("safe mode violation not detected");\
27 }catch(const safe_mode_exception& e){\
28 if(e.error_code!=(err))throw std::runtime_error(\
29 "safe mode violation not expected");\
30 }
31
32 template<typename T> void prevent_unused_var_warning(const T&){}
33
34 template<typename Policy>
35 static void local_test_safe_mode(
36 std::forward_iterator_tag
37 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
38 {
39 typedef typename Policy::container container;
40 typedef typename Policy::index_type index_type;
41 typedef typename index_type::value_type value_type;
42 typedef typename index_type::iterator iterator;
43
44 container c,c2;
45 index_type& i=Policy::index_from_container(c);
46 index_type& i2=Policy::index_from_container(c2);
47 Policy::insert(i,Policy::some_value());
48
49 TRY_SAFE_MODE
50 iterator it;
51 iterator it2=i.begin();
52 it2=it;
53 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
54
55 TRY_SAFE_MODE
56 iterator it;
57 value_type e=*it;
58 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
59
60 TRY_SAFE_MODE
61 iterator it=i.end();
62 value_type e=*it;
63 CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
64
65 TRY_SAFE_MODE
66 iterator it=i.end();
67 ++it;
68 CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator)
69
70 TRY_SAFE_MODE
71 iterator it;
72 iterator it2;
73 bool b=(it==it2);
74 prevent_unused_var_warning(b);
75 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
76
77 TRY_SAFE_MODE
78 iterator it=i.begin();
79 iterator it2;
80 bool b=(it==it2);
81 prevent_unused_var_warning(b);
82 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
83
84 TRY_SAFE_MODE
85 iterator it=i.begin();
86 iterator it2=i2.begin();
87 bool b=(it==it2);
88 prevent_unused_var_warning(b);
89 CATCH_SAFE_MODE(safe_mode::not_same_owner)
90
91 TRY_SAFE_MODE
92 i.erase(i.end(),i.begin());
93 CATCH_SAFE_MODE(safe_mode::invalid_range)
94
95 TRY_SAFE_MODE
96 iterator it;
97 Policy::insert(i,it,Policy::some_value());
98 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
99
100 TRY_SAFE_MODE
101 i.erase(i.end());
102 CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
103
104 TRY_SAFE_MODE
105 iterator it=i.begin();
106 Policy::insert(i2,it,Policy::some_value());
107 CATCH_SAFE_MODE(safe_mode::not_owner)
108
109 TRY_SAFE_MODE
110 iterator it=i.begin();
111 iterator it2=i2.end();
112 i2.erase(it,it2);
113 CATCH_SAFE_MODE(safe_mode::not_owner)
114
115 TRY_SAFE_MODE
116 iterator it=Policy::insert(i,Policy::another_value());
117 i.erase(it);
118 i.erase(it);
119 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
120
121 TRY_SAFE_MODE
122 container c3(c);
123 index_type& i3=Policy::index_from_container(c3);
124 iterator it=Policy::insert(i3,Policy::another_value());
125 i3.clear();
126 i3.erase(it);
127 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
128
129 TRY_SAFE_MODE
130 iterator it;
131 {
132 container c3;
133 index_type& i3=Policy::index_from_container(c3);
134 it=i3.end();
135 }
136 it=it;
137 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
138
139 TRY_SAFE_MODE
140 iterator it;
141 {
142 container c3;
143 index_type& i3=Policy::index_from_container(c3);
144 it=Policy::insert(i3,Policy::some_value());
145 }
146 value_type e=*it;
147 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
148
149 TRY_SAFE_MODE
150 iterator it;
151 {
152 container c3;
153 index_type& i3=Policy::index_from_container(c3);
154 it=Policy::insert(i3,Policy::some_value());
155 }
156 iterator it2;
157 it2=it;
158 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
159
160 TRY_SAFE_MODE
161 container c3(c);
162 container c4;
163 index_type& i3=Policy::index_from_container(c3);
164 index_type& i4=Policy::index_from_container(c4);
165 iterator it=i3.begin();
166 i3.swap(i4);
167 i3.erase(it);
168 CATCH_SAFE_MODE(safe_mode::not_owner)
169
170 /* this, unlike the previous case, is indeed correct, test safe mode
171 * gets it right
172 */
173 {
174 container c3(c);
175 container c4;
176 index_type& i3=Policy::index_from_container(c3);
177 index_type& i4=Policy::index_from_container(c4);
178 iterator it=i3.begin();
179 i3.swap(i4);
180 i4.erase(it);
181 }
182
183 TRY_SAFE_MODE
184 iterator it=i.end();
185 typename container::iterator it2=project<0>(c2,it);
186 CATCH_SAFE_MODE(safe_mode::not_owner)
187
188 TRY_SAFE_MODE
189 iterator it=Policy::insert(i,Policy::another_value());
190 typename container::iterator it2=project<0>(c,it);
191 i.erase(it);
192 value_type e=*it2;
193 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
194
195 /* testcase for bug reported at
196 * http://lists.boost.org/boost-users/2006/02/17230.php
197 */
198 {
199 container c3(c);
200 index_type& i3=Policy::index_from_container(c3);
201 iterator it=i3.end();
202 i3.clear();
203 it=i3.end();
204 }
205
206 /* testcase for doppelganger bug of that discovered for STLport at
207 * http://lists.boost.org/Archives/boost/2006/04/102740.php
208 */
209 {
210 container c3;
211 index_type& i3=Policy::index_from_container(c3);
212 iterator it=i3.end();
213 i3.clear();
214 it=it;
215 BOOST_TEST(it==i3.end());
216 }
217 }
218
219 template<typename Policy>
220 static void local_test_safe_mode(
221 std::bidirectional_iterator_tag
222 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
223 {
224 ::local_test_safe_mode<Policy>(std::forward_iterator_tag());
225
226 typedef typename Policy::container container;
227 typedef typename Policy::index_type index_type;
228 typedef typename index_type::iterator iterator;
229
230 container c;
231 index_type& i=Policy::index_from_container(c);
232 Policy::insert(i,Policy::some_value());
233
234 TRY_SAFE_MODE
235 iterator it=i.begin();
236 --it;
237 CATCH_SAFE_MODE(safe_mode::not_decrementable_iterator)
238 }
239
240 template<typename Policy>
241 static void local_test_safe_mode(
242 std::random_access_iterator_tag
243 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
244 {
245 ::local_test_safe_mode<Policy>(std::bidirectional_iterator_tag());
246
247 typedef typename Policy::container container;
248 typedef typename Policy::index_type index_type;
249 typedef typename index_type::iterator iterator;
250
251 container c;
252 index_type& i=Policy::index_from_container(c);
253 Policy::insert(i,Policy::some_value());
254
255 TRY_SAFE_MODE
256 iterator it=i.begin();
257 it+=2;
258 CATCH_SAFE_MODE(safe_mode::out_of_bounds)
259
260 TRY_SAFE_MODE
261 iterator it=i.begin();
262 it-=1;
263 CATCH_SAFE_MODE(safe_mode::out_of_bounds)
264 }
265
266 template<typename Policy>
267 static void local_test_safe_mode()
268 {
269 typedef typename Policy::index_type::iterator::iterator_category category;
270 ::local_test_safe_mode<Policy>(category());
271 }
272
273 template<typename Policy>
274 static void local_test_safe_mode_with_rearrange()
275 {
276 ::local_test_safe_mode<Policy>();
277
278 typedef typename Policy::container container;
279 typedef typename Policy::index_type index_type;
280 typedef typename index_type::iterator iterator;
281
282 container c;
283 index_type& i=Policy::index_from_container(c);
284 Policy::insert(i,Policy::some_value());
285
286 TRY_SAFE_MODE
287 iterator it;
288 i.splice(it,i,i.begin(),i.end());
289 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
290
291 TRY_SAFE_MODE
292 container c2(c);
293 index_type& i2=Policy::index_from_container(c2);
294 iterator it2=i2.begin();
295 iterator it=i.begin();
296 i.splice(it2,i2,it);
297 CATCH_SAFE_MODE(safe_mode::not_owner)
298
299 TRY_SAFE_MODE
300 i.splice(i.begin(),i,i.begin(),i.end());
301 CATCH_SAFE_MODE(safe_mode::inside_range)
302
303 TRY_SAFE_MODE
304 i.splice(i.begin(),i,i.end(),i.begin());
305 CATCH_SAFE_MODE(safe_mode::invalid_range)
306
307 TRY_SAFE_MODE
308 i.splice(i.begin(),i);
309 CATCH_SAFE_MODE(safe_mode::same_container)
310
311 TRY_SAFE_MODE
312 iterator it;
313 i.relocate(it,i.begin(),i.end());
314 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
315
316 TRY_SAFE_MODE
317 i.relocate(i.begin(),i.begin(),i.end());
318 CATCH_SAFE_MODE(safe_mode::inside_range)
319
320 TRY_SAFE_MODE
321 i.relocate(i.begin(),i.end(),i.begin());
322 CATCH_SAFE_MODE(safe_mode::invalid_range)
323 }
324
325 template<typename MultiIndexContainer,int N>
326 struct index_policy_base
327 {
328 typedef MultiIndexContainer container;
329 typedef typename nth_index<container,N>::type index_type;
330
331 static index_type& index_from_container(container& c){return get<N>(c);}
332 };
333
334 template<typename MultiIndexContainer,int N>
335 struct key_based_index_policy_base:
336 index_policy_base<MultiIndexContainer,N>
337 {
338 typedef index_policy_base<MultiIndexContainer,N> super;
339
340 typedef typename super::container container;
341 typedef typename super::index_type index_type;
342 typedef typename index_type::value_type value_type;
343 typedef typename index_type::iterator iterator;
344
345 static iterator insert(index_type& i,const value_type& v)
346 {
347 return i.insert(v).first;
348 }
349
350 static iterator insert(index_type& i,iterator it,const value_type& v)
351 {
352 return i.insert(it,v);
353 }
354 };
355
356 template<typename MultiIndexContainer,int N>
357 struct non_key_based_index_policy_base:
358 index_policy_base<MultiIndexContainer,N>
359 {
360 typedef index_policy_base<MultiIndexContainer,N> super;
361
362 typedef typename super::container container;
363 typedef typename super::index_type index_type;
364 typedef typename index_type::value_type value_type;
365 typedef typename index_type::iterator iterator;
366
367 static iterator insert(index_type& i,const value_type& v)
368 {
369 return i.push_back(v).first;
370 }
371
372 static iterator insert(index_type& i,iterator it,const value_type& v)
373 {
374 return i.insert(it,v).first;
375 }
376 };
377
378 struct employee_set_policy_base
379 {
380 static employee some_value(){return employee(0,"Joe",31,1123);}
381 static employee another_value(){return employee(1,"Robert",27,5601);}
382 };
383
384 struct employee_set_policy:
385 employee_set_policy_base,
386 key_based_index_policy_base<employee_set,0>
387 {};
388
389 struct employee_set_by_name_policy:
390 employee_set_policy_base,
391 key_based_index_policy_base<employee_set,1>
392 {};
393
394 struct employee_set_as_inserted_policy:
395 employee_set_policy_base,
396 non_key_based_index_policy_base<employee_set,3>
397 {};
398
399 struct employee_set_randomly_policy:
400 employee_set_policy_base,
401 non_key_based_index_policy_base<employee_set,5>
402 {};
403
404 template<typename IntegralBimap>
405 static void test_integral_bimap()
406 {
407 typedef typename IntegralBimap::value_type value_type;
408 typedef typename IntegralBimap::iterator iterator;
409
410 TRY_SAFE_MODE
411 IntegralBimap bm;
412 iterator it=bm.insert(value_type(0,0)).first;
413 bm.insert(value_type(1,1));
414 bm.modify(it,increment_first);
415 value_type v=*it;
416 prevent_unused_var_warning(v);
417 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
418
419 TRY_SAFE_MODE
420 IntegralBimap bm;
421 iterator it=bm.insert(value_type(0,0)).first;
422 bm.insert(value_type(1,1));
423 bm.modify(it,increment_second);
424 pair_of_ints v=*it;
425 prevent_unused_var_warning(v);
426 CATCH_SAFE_MODE(safe_mode::invalid_iterator)
427 }
428
429 void test_safe_mode()
430 {
431 local_test_safe_mode<employee_set_policy>();
432 local_test_safe_mode<employee_set_by_name_policy>();
433 local_test_safe_mode_with_rearrange<employee_set_as_inserted_policy>();
434 local_test_safe_mode_with_rearrange<employee_set_randomly_policy>();
435
436 typedef multi_index_container<
437 pair_of_ints,
438 indexed_by<
439 ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
440 ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
441 > bimap0_type;
442
443 test_integral_bimap<bimap0_type>();
444
445 typedef multi_index_container<
446 pair_of_ints,
447 indexed_by<
448 ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
449 hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
450 > bimap1_type;
451
452 test_integral_bimap<bimap1_type>();
453
454 typedef multi_index_container<
455 pair_of_ints,
456 indexed_by<
457 hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
458 ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
459 > bimap2_type;
460
461 test_integral_bimap<bimap2_type>();
462
463 typedef multi_index_container<
464 pair_of_ints,
465 indexed_by<
466 hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
467 hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
468 > bimap3_type;
469
470 test_integral_bimap<bimap3_type>();
471 }