1 /* Boost.MultiIndex test for replace(), modify() and modify_key().
3 * Copyright 2003-2018 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_update.hpp"
13 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
16 #include "pre_multi_index.hpp"
17 #include "employee.hpp"
18 #include "pair_of_ints.hpp"
19 #include <boost/detail/lightweight_test.hpp>
20 #include <boost/next_prior.hpp>
25 void operator()(const T
&)const{}
31 std::size_t operator()(const T
&)const{return 0;}
36 assign_value(int n
):n_(n
){}
38 void operator()(int& x
)const{x
=n_
;}
43 template<class MultiIndexContainer
>
44 void test_stable_update()
46 typedef typename
MultiIndexContainer::iterator iterator
;
47 typedef typename
MultiIndexContainer::size_type size_type
;
48 typedef typename
MultiIndexContainer::difference_type difference_type
;
50 MultiIndexContainer c
;
52 c
.insert(1);c
.insert(1);
53 c
.insert(2);c
.insert(2);c
.insert(2);c
.insert(2);
55 c
.insert(4);c
.insert(4);c
.insert(4);
56 c
.insert(5);c
.insert(5);
60 c
.count(0)+c
.count(1)+c
.count(2)+c
.count(3)+
61 c
.count(4)+c
.count(5)+c
.count(6)+c
.count(7);
63 for(size_type n
=c
.size();n
--;){
64 iterator it
=boost::next(c
.begin(),(difference_type
)n
);
67 BOOST_TEST((size_type
)std::distance(c
.begin(),it
)==n
);
69 c
.modify(it
,do_nothing());
70 BOOST_TEST((size_type
)std::distance(c
.begin(),it
)==n
);
72 c
.modify(it
,do_nothing(),do_nothing());
73 BOOST_TEST((size_type
)std::distance(c
.begin(),it
)==n
);
75 for(int i
=0;i
<=8;++i
){
76 MultiIndexContainer
cpy(c
);
77 bool b
=c
.modify(it
,assign_value(i
),assign_value(*it
));
78 BOOST_TEST(b
||(size_type
)std::distance(c
.begin(),it
)==n
);
79 BOOST_TEST(c
.count(0)+c
.count(1)+c
.count(2)+c
.count(3)+c
.count(4)+
80 c
.count(5)+c
.count(6)+c
.count(7)+c
.count(8)==num_elems
);
83 it
=boost::next(c
.begin(),(difference_type
)n
);
89 using namespace boost::multi_index
;
94 employee_set_as_inserted
& i
=get
<as_inserted
>(es
);
95 employee_set_randomly
& r
=get
<randomly
>(es
);
97 es
.insert(employee(0,"Joe",31,1123));
98 es
.insert(employee(1,"Robert",27,5601));
99 es
.insert(employee(2,"John",40,7889));
100 es
.insert(employee(3,"Olbert",20,9012));
101 es
.insert(employee(4,"John",57,1002));
103 employee_set::iterator it
=es
.find(employee(0,"Joe",31,1123));
104 employee_set_as_inserted::iterator it1
=
105 project
<as_inserted
>(es
,get
<name
>(es
).find("Olbert"));
106 employee_set_randomly::iterator it2
=
107 project
<randomly
>(es
,get
<age
>(es
).find(57));
109 BOOST_TEST(es
.replace(it
,*it
));
110 BOOST_TEST(i
.replace(it1
,*it1
));
111 BOOST_TEST(r
.replace(it2
,*it2
));
112 BOOST_TEST(!es
.replace(it
,employee(3,"Joe",31,1123))&&it
->id
==0);
113 BOOST_TEST(es
.replace(it
,employee(0,"Joe",32,1123))&&it
->age
==32);
114 BOOST_TEST(i
.replace(it1
,employee(3,"Albert",20,9012))&&it1
->name
==
116 BOOST_TEST(!r
.replace(it2
,employee(4,"John",57,5601)));
119 typedef multi_index_container
<
122 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
123 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)>,
128 nth_index
<int_int_set
,1>::type
& ii1
=get
<1>(iis
);
129 nth_index
<int_int_set
,2>::type
& ii2
=get
<2>(iis
);
130 iis
.insert(pair_of_ints(0,0));
131 iis
.insert(pair_of_ints(5,5));
132 iis
.insert(pair_of_ints(10,10));
134 BOOST_TEST(!iis
.replace(iis
.begin(),pair_of_ints(5,0)));
135 BOOST_TEST(!ii2
.replace(ii2
.begin(),pair_of_ints(0,5)));
136 BOOST_TEST(!ii1
.replace(project
<1>(iis
,iis
.begin()),pair_of_ints(5,11)));
137 BOOST_TEST(!iis
.replace(iis
.begin(),pair_of_ints(11,5)));
138 BOOST_TEST(!iis
.replace(boost::next(iis
.begin()),pair_of_ints(10,5)));
139 BOOST_TEST(!ii1
.replace(
140 project
<1>(iis
,boost::next(iis
.begin())),pair_of_ints(5,10)));
141 BOOST_TEST(!iis
.replace(boost::prior(iis
.end()),pair_of_ints(5,10)));
142 BOOST_TEST(!ii2
.replace(boost::prior(ii2
.end()),pair_of_ints(10,5)));
144 BOOST_TEST(iis
.modify(iis
.begin(),increment_first
));
145 BOOST_TEST(ii2
.modify(ii2
.begin(),increment_first
));
146 BOOST_TEST(ii1
.modify(project
<1>(iis
,iis
.begin()),increment_first
));
147 BOOST_TEST(ii2
.modify(ii2
.begin(),increment_first
,decrement_first
));
149 BOOST_TEST(!iis
.modify(iis
.begin(),increment_first
,decrement_first
));
150 BOOST_TEST(iis
.size()==3);
152 BOOST_TEST(!iis
.modify(iis
.begin(),increment_first
));
153 BOOST_TEST(iis
.size()==2);
155 iis
.insert(pair_of_ints(0,0));
156 BOOST_TEST(ii2
.modify(boost::prior(ii2
.end()),increment_second
));
157 BOOST_TEST(iis
.modify(iis
.begin(),increment_second
));
158 BOOST_TEST(ii2
.modify(boost::prior(ii2
.end()),increment_second
));
159 BOOST_TEST(iis
.modify(iis
.begin(),increment_second
,decrement_second
));
161 BOOST_TEST(!ii2
.modify(
162 boost::prior(ii2
.end()),increment_second
,decrement_second
));
163 BOOST_TEST(ii2
.size()==3);
165 BOOST_TEST(!ii2
.modify(boost::prior(ii2
.end()),increment_second
));
166 BOOST_TEST(ii2
.size()==2);
168 iis
.insert(pair_of_ints(0,0));
169 BOOST_TEST(iis
.modify_key(iis
.begin(),increment_int
));
170 BOOST_TEST(iis
.modify_key(iis
.begin(),increment_int
,decrement_int
));
171 BOOST_TEST(iis
.modify_key(iis
.begin(),increment_int
));
172 BOOST_TEST(iis
.modify_key(iis
.begin(),increment_int
));
174 BOOST_TEST(!iis
.modify_key(iis
.begin(),increment_int
,decrement_int
));
175 BOOST_TEST(iis
.size()==3);
177 BOOST_TEST(!iis
.modify_key(iis
.begin(),increment_int
));
178 BOOST_TEST(iis
.size()==2);
180 nth_index_iterator
<int_int_set
,1>::type it_
=ii1
.find(5);
181 BOOST_TEST(ii1
.modify_key(it_
,increment_int
));
182 BOOST_TEST(ii1
.modify_key(it_
,increment_int
));
183 BOOST_TEST(ii1
.modify_key(it_
,increment_int
,decrement_int
));
184 BOOST_TEST(ii1
.modify_key(it_
,increment_int
));
186 BOOST_TEST(!ii1
.modify_key(it_
,increment_int
,decrement_int
));
187 BOOST_TEST(ii1
.size()==2);
189 BOOST_TEST(!ii1
.modify_key(it_
,increment_int
));
190 BOOST_TEST(ii1
.size()==1);
193 typedef multi_index_container
<
196 hashed_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,first
)>,
198 ordered_unique
<BOOST_MULTI_INDEX_MEMBER(pair_of_ints
,int,second
)> > >
202 nth_index
<int_int_set
,1>::type
& ii1
=get
<1>(iis
);
203 int_int_set::iterator p1
=iis
.insert(pair_of_ints(0,0)).first
;
204 int_int_set::iterator p2
=iis
.insert(pair_of_ints(5,5)).first
;
205 int_int_set::iterator p3
=iis
.insert(pair_of_ints(10,10)).first
;
207 BOOST_TEST(!iis
.replace(p1
,pair_of_ints(5,0)));
208 BOOST_TEST(!ii1
.replace(ii1
.begin(),pair_of_ints(0,5)));
209 BOOST_TEST(!iis
.replace(p1
,pair_of_ints(5,11)));
210 BOOST_TEST(!iis
.replace(p1
,pair_of_ints(11,5)));
211 BOOST_TEST(!iis
.replace(p2
,pair_of_ints(10,5)));
212 BOOST_TEST(!iis
.replace(p2
,pair_of_ints(5,10)));
213 BOOST_TEST(!iis
.replace(p3
,pair_of_ints(5,10)));
214 BOOST_TEST(!ii1
.replace(boost::prior(ii1
.end()),pair_of_ints(10,5)));
216 BOOST_TEST(iis
.modify(p1
,increment_first
));
217 BOOST_TEST(ii1
.modify(ii1
.begin(),increment_first
));
218 BOOST_TEST(iis
.modify(p1
,increment_first
));
219 BOOST_TEST(ii1
.modify(ii1
.begin(),increment_first
,decrement_first
));
221 BOOST_TEST(!iis
.modify(p1
,increment_first
,decrement_first
));
222 BOOST_TEST(iis
.size()==3);
224 BOOST_TEST(!iis
.modify(p1
,increment_first
));
225 BOOST_TEST(iis
.size()==2);
227 p1
=iis
.insert(pair_of_ints(0,0)).first
;
228 BOOST_TEST(ii1
.modify(boost::prior(ii1
.end()),increment_second
));
229 BOOST_TEST(iis
.modify(p1
,increment_second
,decrement_second
));
230 BOOST_TEST(ii1
.modify(boost::prior(ii1
.end()),increment_second
));
231 BOOST_TEST(iis
.modify(p1
,increment_second
));
233 BOOST_TEST(!ii1
.modify(
234 boost::prior(ii1
.end()),increment_second
,decrement_second
));
235 BOOST_TEST(ii1
.size()==3);
237 BOOST_TEST(!ii1
.modify(boost::prior(ii1
.end()),increment_second
));
238 BOOST_TEST(ii1
.size()==2);
241 typedef multi_index_container
<
244 ordered_non_unique
<identity
<int> >
247 test_stable_update
<int_multiset
>();
249 typedef multi_index_container
<
252 hashed_unique
<identity
<int> >
255 test_stable_update
<int_hashed_set
>();
257 typedef multi_index_container
<
260 hashed_unique
<identity
<int> >
262 > int_hashed_multiset
;
263 test_stable_update
<int_hashed_multiset
>();
265 typedef multi_index_container
<
268 hashed_unique
<identity
<int>,null_hash
>
270 > degenerate_int_hashed_set
;
271 test_stable_update
<degenerate_int_hashed_set
>();
273 typedef multi_index_container
<
276 hashed_non_unique
<identity
<int>,null_hash
>
278 > degenerate_int_hashed_multiset
;
279 test_stable_update
<degenerate_int_hashed_multiset
>();