1 /* Boost.MultiIndex test for safe_mode.
3 * Copyright 2003-2021 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)
8 * See http://www.boost.org/libs/multi_index for library home page.
11 #include "test_safe_mode.hpp"
13 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
14 #include <boost/move/core.hpp>
15 #include <boost/move/utility_core.hpp>
16 #include "pre_multi_index.hpp"
17 #include "employee.hpp"
18 #include "pair_of_ints.hpp"
20 #include <boost/detail/lightweight_test.hpp>
22 using namespace boost::multi_index
;
24 #define TRY_SAFE_MODE \
27 #define CATCH_SAFE_MODE(err) \
28 throw std::runtime_error("safe mode violation not detected");\
29 }catch(const safe_mode_exception& e){\
30 if(e.error_code!=(err))throw std::runtime_error(\
31 "safe mode violation not expected");\
34 template<typename T
> void prevent_unused_var_warning(const T
&){}
36 template<typename Policy
>
37 static void local_test_safe_mode(
38 std::forward_iterator_tag
39 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy
))
41 typedef typename
Policy::container container
;
42 typedef typename
Policy::allocator_type allocator_type
;
43 typedef typename
Policy::index_type index_type
;
44 typedef typename
index_type::value_type value_type
;
45 typedef typename
index_type::iterator iterator
;
46 typedef typename
index_type::node_type node_type
;
49 index_type
& i
=Policy::index_from_container(c
);
50 index_type
& i2
=Policy::index_from_container(c2
);
51 Policy::insert(i
,Policy::some_value());
55 iterator it2
=i
.begin();
57 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
62 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
67 CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator
)
72 CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator
)
78 prevent_unused_var_warning(b
);
79 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
82 iterator it
=i
.begin();
85 prevent_unused_var_warning(b
);
86 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
89 iterator it
=i
.begin();
90 iterator it2
=i2
.begin();
92 prevent_unused_var_warning(b
);
93 CATCH_SAFE_MODE(safe_mode::not_same_owner
)
96 i
.erase(i
.end(),i
.begin());
97 CATCH_SAFE_MODE(safe_mode::invalid_range
)
101 Policy::insert(i
,it
,Policy::some_value());
102 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
106 CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator
)
109 iterator it
=i
.begin();
110 Policy::insert(i2
,it
,Policy::some_value());
111 CATCH_SAFE_MODE(safe_mode::not_owner
)
114 iterator it
=i
.begin();
115 iterator it2
=i2
.end();
117 CATCH_SAFE_MODE(safe_mode::not_owner
)
120 iterator it
=Policy::insert(i
,Policy::another_value());
123 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
127 index_type
& i3
=Policy::index_from_container(c3
);
128 iterator it
=Policy::insert(i3
,Policy::another_value());
131 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
137 index_type
& i3
=Policy::index_from_container(c3
);
142 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
148 index_type
& i3
=Policy::index_from_container(c3
);
149 it
=Policy::insert(i3
,Policy::some_value());
152 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
158 index_type
& i3
=Policy::index_from_container(c3
);
159 it
=Policy::insert(i3
,Policy::some_value());
163 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
168 index_type
& i3
=Policy::index_from_container(c3
);
169 index_type
& i4
=Policy::index_from_container(c4
);
170 iterator it
=i3
.begin();
173 CATCH_SAFE_MODE(safe_mode::not_owner
)
175 /* this, unlike the previous case, is indeed correct, test safe mode
181 index_type
& i3
=Policy::index_from_container(c3
);
182 index_type
& i4
=Policy::index_from_container(c4
);
183 iterator it
=i3
.begin();
190 typename
container::iterator it2
=project
<0>(c2
,it
);
191 CATCH_SAFE_MODE(safe_mode::not_owner
)
194 iterator it
=Policy::insert(i
,Policy::another_value());
195 typename
container::iterator it2
=project
<0>(c
,it
);
198 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
201 iterator it
=Policy::insert(i
,Policy::another_value());
202 node_type nh
=i
.extract(it
);
205 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
208 iterator it
=Policy::insert(i
,Policy::another_value());
209 node_type nh
=i
.extract(it
);
210 container
c3(c2
,allocator_type(-1));
211 index_type
& i3
=Policy::index_from_container(c3
);
212 Policy::insert(i3
,boost::move(nh
));
213 CATCH_SAFE_MODE(safe_mode::unequal_allocators
)
215 /* testcase for bug reported at
216 * http://lists.boost.org/boost-users/2006/02/17230.php
220 index_type
& i3
=Policy::index_from_container(c3
);
221 iterator it
=i3
.end();
226 /* testcase for doppelganger bug of that discovered for STLport at
227 * http://lists.boost.org/Archives/boost/2006/04/102740.php
231 index_type
& i3
=Policy::index_from_container(c3
);
232 iterator it
=i3
.end();
235 BOOST_TEST(it2
==i3
.end());
239 template<typename Policy
>
240 static void local_test_safe_mode(
241 std::bidirectional_iterator_tag
242 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy
))
244 ::local_test_safe_mode
<Policy
>(std::forward_iterator_tag());
246 typedef typename
Policy::container container
;
247 typedef typename
Policy::index_type index_type
;
248 typedef typename
index_type::iterator iterator
;
251 index_type
& i
=Policy::index_from_container(c
);
252 Policy::insert(i
,Policy::some_value());
255 iterator it
=i
.begin();
257 CATCH_SAFE_MODE(safe_mode::not_decrementable_iterator
)
260 template<typename Policy
>
261 static void local_test_safe_mode(
262 std::random_access_iterator_tag
263 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy
))
265 ::local_test_safe_mode
<Policy
>(std::bidirectional_iterator_tag());
267 typedef typename
Policy::container container
;
268 typedef typename
Policy::index_type index_type
;
269 typedef typename
index_type::iterator iterator
;
272 index_type
& i
=Policy::index_from_container(c
);
273 Policy::insert(i
,Policy::some_value());
276 iterator it
=i
.begin();
278 CATCH_SAFE_MODE(safe_mode::out_of_bounds
)
281 iterator it
=i
.begin();
283 CATCH_SAFE_MODE(safe_mode::out_of_bounds
)
286 template<typename Policy
>
287 static void local_test_safe_mode()
289 typedef typename
Policy::index_type::iterator::iterator_category category
;
290 ::local_test_safe_mode
<Policy
>(category());
293 template<typename Policy
>
294 static void local_test_safe_mode_with_rearrange()
296 ::local_test_safe_mode
<Policy
>();
298 typedef typename
Policy::container container
;
299 typedef typename
Policy::index_type index_type
;
300 typedef typename
index_type::iterator iterator
;
303 index_type
& i
=Policy::index_from_container(c
);
304 Policy::insert(i
,Policy::some_value());
308 i
.splice(it
,i
,i
.begin(),i
.end());
309 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
313 index_type
& i2
=Policy::index_from_container(c2
);
314 iterator it2
=i2
.begin();
315 iterator it
=i
.begin();
317 CATCH_SAFE_MODE(safe_mode::not_owner
)
320 i
.splice(i
.begin(),i
,i
.begin(),i
.end());
321 CATCH_SAFE_MODE(safe_mode::inside_range
)
324 i
.splice(i
.begin(),i
,i
.end(),i
.begin());
325 CATCH_SAFE_MODE(safe_mode::invalid_range
)
328 i
.splice(i
.begin(),i
);
329 CATCH_SAFE_MODE(safe_mode::inside_range
)
333 i
.relocate(it
,i
.begin(),i
.end());
334 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
337 i
.relocate(i
.begin(),i
.begin(),i
.end());
338 CATCH_SAFE_MODE(safe_mode::inside_range
)
341 i
.relocate(i
.begin(),i
.end(),i
.begin());
342 CATCH_SAFE_MODE(safe_mode::invalid_range
)
345 template<typename MultiIndexContainer
,int N
>
346 struct index_policy_base
348 typedef MultiIndexContainer container
;
349 typedef typename
container::allocator_type allocator_type
;
350 typedef typename nth_index
<container
,N
>::type index_type
;
352 static index_type
& index_from_container(container
& c
){return get
<N
>(c
);}
355 template<typename MultiIndexContainer
,int N
>
356 struct key_based_index_policy_base
:
357 index_policy_base
<MultiIndexContainer
,N
>
359 typedef index_policy_base
<MultiIndexContainer
,N
> super
;
361 typedef typename
super::container container
;
362 typedef typename
super::index_type index_type
;
363 typedef typename
index_type::value_type value_type
;
364 typedef typename
index_type::iterator iterator
;
365 typedef typename
index_type::node_type node_type
;
367 static iterator
insert(index_type
& i
,const value_type
& v
)
369 return i
.insert(v
).first
;
372 static iterator
insert(index_type
& i
,iterator it
,const value_type
& v
)
374 return i
.insert(it
,v
);
377 static void insert(index_type
& i
,BOOST_RV_REF(node_type
) nh
)
379 i
.insert(boost::move(nh
));
383 template<typename MultiIndexContainer
,int N
>
384 struct non_key_based_index_policy_base
:
385 index_policy_base
<MultiIndexContainer
,N
>
387 typedef index_policy_base
<MultiIndexContainer
,N
> super
;
389 typedef typename
super::container container
;
390 typedef typename
super::index_type index_type
;
391 typedef typename
index_type::value_type value_type
;
392 typedef typename
index_type::iterator iterator
;
393 typedef typename
index_type::node_type node_type
;
395 static iterator
insert(index_type
& i
,const value_type
& v
)
397 return i
.push_back(v
).first
;
400 static iterator
insert(index_type
& i
,iterator it
,const value_type
& v
)
402 return i
.insert(it
,v
).first
;
405 static void insert(index_type
& i
,BOOST_RV_REF(node_type
) nh
)
407 i
.insert(i
.end(),boost::move(nh
));
411 struct employee_set_policy_base
413 static employee
some_value(){return employee(0,"Joe",31,1123);}
414 static employee
another_value(){return employee(1,"Robert",27,5601);}
417 struct employee_set_policy
:
418 employee_set_policy_base
,
419 key_based_index_policy_base
<employee_set
,0>
422 struct employee_set_by_name_policy
:
423 employee_set_policy_base
,
424 key_based_index_policy_base
<employee_set
,1>
427 struct employee_set_as_inserted_policy
:
428 employee_set_policy_base
,
429 non_key_based_index_policy_base
<employee_set
,3>
432 struct employee_set_randomly_policy
:
433 employee_set_policy_base
,
434 non_key_based_index_policy_base
<employee_set
,5>
437 template<typename IntegralBimap
>
438 static void test_integral_bimap()
440 typedef typename
IntegralBimap::value_type value_type
;
441 typedef typename
IntegralBimap::iterator iterator
;
445 iterator it
=bm
.insert(value_type(0,0)).first
;
446 bm
.insert(value_type(1,1));
447 bm
.modify(it
,increment_first
);
449 prevent_unused_var_warning(v
);
450 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
454 iterator it
=bm
.insert(value_type(0,0)).first
;
455 bm
.insert(value_type(1,1));
456 bm
.modify(it
,increment_second
);
458 prevent_unused_var_warning(v
);
459 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
462 void test_safe_mode()
464 local_test_safe_mode
<employee_set_policy
>();
465 local_test_safe_mode
<employee_set_by_name_policy
>();
466 local_test_safe_mode_with_rearrange
<employee_set_as_inserted_policy
>();
467 local_test_safe_mode_with_rearrange
<employee_set_randomly_policy
>();
469 typedef multi_index_container
<
472 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
473 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
476 test_integral_bimap
<bimap0_type
>();
478 typedef multi_index_container
<
481 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
482 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
485 test_integral_bimap
<bimap1_type
>();
487 typedef multi_index_container
<
490 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
491 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
494 test_integral_bimap
<bimap2_type
>();
496 typedef multi_index_container
<
499 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
500 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
503 test_integral_bimap
<bimap3_type
>();