1 /* Boost.MultiIndex test for safe_mode.
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)
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 "pre_multi_index.hpp"
15 #include "employee.hpp"
16 #include "pair_of_ints.hpp"
18 #include <boost/detail/lightweight_test.hpp>
20 using namespace boost::multi_index
;
22 #define TRY_SAFE_MODE \
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");\
32 template<typename T
> void prevent_unused_var_warning(const T
&){}
34 template<typename Policy
>
35 static void local_test_safe_mode(
36 std::forward_iterator_tag
37 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy
))
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
;
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());
51 iterator it2
=i
.begin();
53 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
58 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
63 CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator
)
68 CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator
)
74 prevent_unused_var_warning(b
);
75 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
78 iterator it
=i
.begin();
81 prevent_unused_var_warning(b
);
82 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
85 iterator it
=i
.begin();
86 iterator it2
=i2
.begin();
88 prevent_unused_var_warning(b
);
89 CATCH_SAFE_MODE(safe_mode::not_same_owner
)
92 i
.erase(i
.end(),i
.begin());
93 CATCH_SAFE_MODE(safe_mode::invalid_range
)
97 Policy::insert(i
,it
,Policy::some_value());
98 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
102 CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator
)
105 iterator it
=i
.begin();
106 Policy::insert(i2
,it
,Policy::some_value());
107 CATCH_SAFE_MODE(safe_mode::not_owner
)
110 iterator it
=i
.begin();
111 iterator it2
=i2
.end();
113 CATCH_SAFE_MODE(safe_mode::not_owner
)
116 iterator it
=Policy::insert(i
,Policy::another_value());
119 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
123 index_type
& i3
=Policy::index_from_container(c3
);
124 iterator it
=Policy::insert(i3
,Policy::another_value());
127 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
133 index_type
& i3
=Policy::index_from_container(c3
);
137 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
143 index_type
& i3
=Policy::index_from_container(c3
);
144 it
=Policy::insert(i3
,Policy::some_value());
147 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
153 index_type
& i3
=Policy::index_from_container(c3
);
154 it
=Policy::insert(i3
,Policy::some_value());
158 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
163 index_type
& i3
=Policy::index_from_container(c3
);
164 index_type
& i4
=Policy::index_from_container(c4
);
165 iterator it
=i3
.begin();
168 CATCH_SAFE_MODE(safe_mode::not_owner
)
170 /* this, unlike the previous case, is indeed correct, test safe mode
176 index_type
& i3
=Policy::index_from_container(c3
);
177 index_type
& i4
=Policy::index_from_container(c4
);
178 iterator it
=i3
.begin();
185 typename
container::iterator it2
=project
<0>(c2
,it
);
186 CATCH_SAFE_MODE(safe_mode::not_owner
)
189 iterator it
=Policy::insert(i
,Policy::another_value());
190 typename
container::iterator it2
=project
<0>(c
,it
);
193 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
195 /* testcase for bug reported at
196 * http://lists.boost.org/boost-users/2006/02/17230.php
200 index_type
& i3
=Policy::index_from_container(c3
);
201 iterator it
=i3
.end();
206 /* testcase for doppelganger bug of that discovered for STLport at
207 * http://lists.boost.org/Archives/boost/2006/04/102740.php
211 index_type
& i3
=Policy::index_from_container(c3
);
212 iterator it
=i3
.end();
215 BOOST_TEST(it
==i3
.end());
219 template<typename Policy
>
220 static void local_test_safe_mode(
221 std::bidirectional_iterator_tag
222 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy
))
224 ::local_test_safe_mode
<Policy
>(std::forward_iterator_tag());
226 typedef typename
Policy::container container
;
227 typedef typename
Policy::index_type index_type
;
228 typedef typename
index_type::iterator iterator
;
231 index_type
& i
=Policy::index_from_container(c
);
232 Policy::insert(i
,Policy::some_value());
235 iterator it
=i
.begin();
237 CATCH_SAFE_MODE(safe_mode::not_decrementable_iterator
)
240 template<typename Policy
>
241 static void local_test_safe_mode(
242 std::random_access_iterator_tag
243 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy
))
245 ::local_test_safe_mode
<Policy
>(std::bidirectional_iterator_tag());
247 typedef typename
Policy::container container
;
248 typedef typename
Policy::index_type index_type
;
249 typedef typename
index_type::iterator iterator
;
252 index_type
& i
=Policy::index_from_container(c
);
253 Policy::insert(i
,Policy::some_value());
256 iterator it
=i
.begin();
258 CATCH_SAFE_MODE(safe_mode::out_of_bounds
)
261 iterator it
=i
.begin();
263 CATCH_SAFE_MODE(safe_mode::out_of_bounds
)
266 template<typename Policy
>
267 static void local_test_safe_mode()
269 typedef typename
Policy::index_type::iterator::iterator_category category
;
270 ::local_test_safe_mode
<Policy
>(category());
273 template<typename Policy
>
274 static void local_test_safe_mode_with_rearrange()
276 ::local_test_safe_mode
<Policy
>();
278 typedef typename
Policy::container container
;
279 typedef typename
Policy::index_type index_type
;
280 typedef typename
index_type::iterator iterator
;
283 index_type
& i
=Policy::index_from_container(c
);
284 Policy::insert(i
,Policy::some_value());
288 i
.splice(it
,i
,i
.begin(),i
.end());
289 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
293 index_type
& i2
=Policy::index_from_container(c2
);
294 iterator it2
=i2
.begin();
295 iterator it
=i
.begin();
297 CATCH_SAFE_MODE(safe_mode::not_owner
)
300 i
.splice(i
.begin(),i
,i
.begin(),i
.end());
301 CATCH_SAFE_MODE(safe_mode::inside_range
)
304 i
.splice(i
.begin(),i
,i
.end(),i
.begin());
305 CATCH_SAFE_MODE(safe_mode::invalid_range
)
308 i
.splice(i
.begin(),i
);
309 CATCH_SAFE_MODE(safe_mode::same_container
)
313 i
.relocate(it
,i
.begin(),i
.end());
314 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
317 i
.relocate(i
.begin(),i
.begin(),i
.end());
318 CATCH_SAFE_MODE(safe_mode::inside_range
)
321 i
.relocate(i
.begin(),i
.end(),i
.begin());
322 CATCH_SAFE_MODE(safe_mode::invalid_range
)
325 template<typename MultiIndexContainer
,int N
>
326 struct index_policy_base
328 typedef MultiIndexContainer container
;
329 typedef typename nth_index
<container
,N
>::type index_type
;
331 static index_type
& index_from_container(container
& c
){return get
<N
>(c
);}
334 template<typename MultiIndexContainer
,int N
>
335 struct key_based_index_policy_base
:
336 index_policy_base
<MultiIndexContainer
,N
>
338 typedef index_policy_base
<MultiIndexContainer
,N
> super
;
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
;
345 static iterator
insert(index_type
& i
,const value_type
& v
)
347 return i
.insert(v
).first
;
350 static iterator
insert(index_type
& i
,iterator it
,const value_type
& v
)
352 return i
.insert(it
,v
);
356 template<typename MultiIndexContainer
,int N
>
357 struct non_key_based_index_policy_base
:
358 index_policy_base
<MultiIndexContainer
,N
>
360 typedef index_policy_base
<MultiIndexContainer
,N
> super
;
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
;
367 static iterator
insert(index_type
& i
,const value_type
& v
)
369 return i
.push_back(v
).first
;
372 static iterator
insert(index_type
& i
,iterator it
,const value_type
& v
)
374 return i
.insert(it
,v
).first
;
378 struct employee_set_policy_base
380 static employee
some_value(){return employee(0,"Joe",31,1123);}
381 static employee
another_value(){return employee(1,"Robert",27,5601);}
384 struct employee_set_policy
:
385 employee_set_policy_base
,
386 key_based_index_policy_base
<employee_set
,0>
389 struct employee_set_by_name_policy
:
390 employee_set_policy_base
,
391 key_based_index_policy_base
<employee_set
,1>
394 struct employee_set_as_inserted_policy
:
395 employee_set_policy_base
,
396 non_key_based_index_policy_base
<employee_set
,3>
399 struct employee_set_randomly_policy
:
400 employee_set_policy_base
,
401 non_key_based_index_policy_base
<employee_set
,5>
404 template<typename IntegralBimap
>
405 static void test_integral_bimap()
407 typedef typename
IntegralBimap::value_type value_type
;
408 typedef typename
IntegralBimap::iterator iterator
;
412 iterator it
=bm
.insert(value_type(0,0)).first
;
413 bm
.insert(value_type(1,1));
414 bm
.modify(it
,increment_first
);
416 prevent_unused_var_warning(v
);
417 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
421 iterator it
=bm
.insert(value_type(0,0)).first
;
422 bm
.insert(value_type(1,1));
423 bm
.modify(it
,increment_second
);
425 prevent_unused_var_warning(v
);
426 CATCH_SAFE_MODE(safe_mode::invalid_iterator
)
429 void test_safe_mode()
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
>();
436 typedef multi_index_container
<
439 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
440 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
443 test_integral_bimap
<bimap0_type
>();
445 typedef multi_index_container
<
448 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
449 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
452 test_integral_bimap
<bimap1_type
>();
454 typedef multi_index_container
<
457 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
458 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
461 test_integral_bimap
<bimap2_type
>();
463 typedef multi_index_container
<
466 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
467 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> >
470 test_integral_bimap
<bimap3_type
>();