1/* Boost.MultiIndex test for copying and assignment.
2 *
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)
7 *
8 * See http://www.boost.org/libs/multi_index for library home page.
9 */
10
11#include "test_copy_assignment.hpp"
12
13#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
14#include <algorithm>
15#include <boost/move/utility_core.hpp>
16#include <list>
17#include <numeric>
18#include <vector>
19#include "pre_multi_index.hpp"
20#include "employee.hpp"
21#include "small_allocator.hpp"
22#include <boost/detail/lightweight_test.hpp>
23
24using namespace boost::multi_index;
25
26#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
27/* The "ISO C++ Template Parser" option makes CW8.3 incorrectly fail at
28 * expressions of the form sizeof(x) where x is an array local to a
29 * template function.
30 */
31
32#pragma parse_func_templ off
33#endif
34
35typedef multi_index_container<int> copyable_and_movable;
36
37struct holder
38{
39 copyable_and_movable c;
40};
41
42template<typename Sequence>
43static void test_assign()
44{
45 Sequence s;
46
47 int a[]={0,1,2,3,4,5};
48 std::size_t sa=sizeof(a)/sizeof(a[0]);
49
50 s.assign(&a[0],&a[sa]);
51 BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
52
53 s.assign((const int*)(&a[0]),(const int*)(&a[sa]));
54 BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
55
56#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
57 s.assign({0,1,2,3,4,5});
58#else
59 s.assign(&a[0],&a[sa]);
60#endif
61
62 BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
63
64 s.assign((std::size_t)18,37);
65 BOOST_TEST(s.size()==18&&std::accumulate(s.begin(),s.end(),0)==666);
66
67 s.assign((std::size_t)12,167);
68 BOOST_TEST(s.size()==12&&std::accumulate(s.begin(),s.end(),0)==2004);
69}
70
71#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
72#pragma parse_func_templ reset
73#endif
74
75template<typename Sequence>
76static void test_integral_assign()
77{
78 /* Special cases described in 23.1.1/9: integral types must not
79 * be taken as iterators in assign(f,l) and insert(p,f,l).
80 */
81
82 Sequence s;
83
84 s.assign(5,10);
85 BOOST_TEST(s.size()==5&&std::accumulate(s.begin(),s.end(),0)==50);
86 s.assign(2u,5u);
87 BOOST_TEST(s.size()==2&&std::accumulate(s.begin(),s.end(),0)==10);
88
89 s.clear();
90 s.insert(s.begin(),5,10);
91 BOOST_TEST(s.size()==5&&std::accumulate(s.begin(),s.end(),0)==50);
92 s.insert(s.begin(),2u,5u);
93 BOOST_TEST(s.size()==7&&std::accumulate(s.begin(),s.end(),0)==60);
94}
95
96employee_set produce_employee_set()
97{
98 employee_set es;
99 es.insert(x: employee(0,"Petr",60,2837));
100 es.insert(x: employee(1,"Jiri",25,2143));
101 es.insert(x: employee(2,"Radka",40,4875));
102 es.insert(x: employee(3,"Milan",38,3474));
103 return es;
104}
105
106void test_copy_assignment()
107{
108 employee_set es;
109 employee_set es2(es);
110
111 employee_set::allocator_type al=es.get_allocator();
112 al=get<1>(m&: es).get_allocator();
113 al=get<2>(m&: es).get_allocator();
114 al=get<3>(m&: es).get_allocator();
115 al=get<4>(m&: es).get_allocator();
116 al=get<5>(m&: es).get_allocator();
117
118 BOOST_TEST(es2.empty());
119
120 es2.insert(x: employee(0,"Joe",31,1123));
121 es2.insert(x: employee(1,"Robert",27,5601));
122 es2.insert(x: employee(2,"John",40,7889));
123 es2.insert(x: employee(2,"Aristotle",2388,3357)); /* clash */
124 es2.insert(x: employee(3,"Albert",20,9012));
125 es2.insert(x: employee(4,"John",57,1002));
126 es2.insert(x: employee(0,"Andrew",60,2302)); /* clash */
127
128 employee_set es3(es2);
129
130 BOOST_TEST(es2==es3);
131 BOOST_TEST(get<2>(es2)==get<2>(es3));
132 BOOST_TEST(get<3>(es2)==get<3>(es3));
133 BOOST_TEST(get<5>(es2)==get<5>(es3));
134
135 employee_set es4=employee_set(non_std_allocator<employee>());
136 employee_set_by_name& i1=get<name>(m&: es4);
137 i1=get<1>(m&: es2);
138
139 BOOST_TEST(es4==es2);
140
141 employee_set es5=employee_set(employee_set::ctor_args_list());
142 employee_set_by_age& i2=get<age>(m&: es5);
143 i2=get<2>(m&: es2);
144
145 BOOST_TEST(i2==get<2>(es2));
146
147 employee_set es6;
148 employee_set_as_inserted& i3=get<as_inserted>(m&: es6);
149 i3=get<3>(m&: es2);
150
151 BOOST_TEST(i3==get<3>(es2));
152
153 employee_set es7;
154 employee_set_randomly& i5=get<randomly>(m&: es7);
155 i5=get<5>(m&: es2);
156
157 BOOST_TEST(i5==get<5>(es2));
158
159#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)&&\
160 !BOOST_WORKAROUND(BOOST_MSVC,==1800) /* MSVC 12.0 chokes on what follows */
161 employee_set es8({{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102}});
162 employee_set es9;
163 es9={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
164 {0,"Rose",40,4512}};
165
166 BOOST_TEST(es8.size()==3);
167 BOOST_TEST(es9==es8);
168
169 es9.clear();
170 get<0>(m&: es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
171 {0,"Rose",40,4512}};
172 BOOST_TEST(es9==es8);
173
174 es9.clear();
175 get<0>(m&: es9)={{0,"Rose",40,4512},{2,"Jo",25,7102},{1,"Mary",38,3345}};
176 BOOST_TEST(es9==es8);
177
178 es9.clear();
179 get<1>(m&: es9)={{1,"Mary",38,3345},{0,"Rose",40,4512},{2,"Jo",25,7102},
180 {0,"Rose",40,4512}};
181 BOOST_TEST(es9==es8);
182
183 es9.clear();
184 get<2>(m&: es9)={{2,"Jo",25,7102},{0,"Rose",40,4512},{1,"Mary",38,3345}};
185 BOOST_TEST(es9==es8);
186
187 es9.clear();
188 get<3>(m&: es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{1,"Mary",38,3345},
189 {2,"Jo",25,7102}};
190 BOOST_TEST(es9==es8);
191
192 es9.clear();
193 get<4>(m&: es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512}};
194 BOOST_TEST(es9==es8);
195
196 es9.clear();
197 get<5>(m&: es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512},
198 {2,"Jo",25,7102}};
199 BOOST_TEST(es9==es8);
200#endif
201
202 employee_set es10(produce_employee_set()),es11(produce_employee_set());
203 BOOST_TEST(es10==es11);
204
205 employee_set es12(boost::move(t&: es10));
206 BOOST_TEST(es10.empty());
207 BOOST_TEST(es11==es12);
208
209 es10=boost::move(t&: es12);
210 BOOST_TEST(es12.empty());
211 BOOST_TEST(es11==es10);
212
213 std::list<employee> l;
214 l.push_back(x: employee(3,"Anna",31,5388));
215 l.push_back(x: employee(1,"Rachel",27,9012));
216 l.push_back(x: employee(2,"Agatha",40,1520));
217
218 employee_set es13(l.begin(),l.end());
219
220 l.sort();
221
222 BOOST_TEST(es13.size()==l.size()&&
223 std::equal(es13.begin(),es13.end(),l.begin()));
224
225 test_assign<multi_index_container<int,indexed_by<sequenced<> > > >();
226 test_integral_assign<
227 multi_index_container<int,indexed_by<sequenced<> > > >();
228
229 test_assign<multi_index_container<int,indexed_by<random_access<> > > >();
230 test_integral_assign<
231 multi_index_container<int,indexed_by<random_access<> > > >();
232
233 /* Testcase for problem described at http://www.boost.org/doc/html/move/
234 * emulation_limitations.html#move.emulation_limitations.assignment_operator
235 */
236
237 holder h((holder()));
238 h=holder();
239
240#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
241{
242 /* testcase for https://svn.boost.org/trac10/ticket/13518 */
243
244 multi_index_container<int> x={};
245}
246#endif
247
248 typedef small_allocator<int> small_alloc;
249 typedef multi_index_container<
250 int,
251 indexed_by<
252 ordered_unique<identity<int> >,
253 ranked_unique<identity<int> >,
254 hashed_unique<identity<int> >,
255 sequenced<>,
256 random_access<>
257 >,
258 small_alloc
259 > small_container;
260 typedef small_container::nth_index<0>::type small_container_0;
261 typedef small_container::nth_index<1>::type small_container_1;
262 typedef small_container::nth_index<2>::type small_container_2;
263 typedef small_container::nth_index<3>::type small_container_3;
264 typedef small_container::nth_index<4>::type small_container_4;
265
266 BOOST_STATIC_ASSERT((
267 boost::is_same<small_container::size_type,small_alloc::size_type>::value));
268 BOOST_STATIC_ASSERT((
269 boost::is_same<
270 small_container::difference_type,small_alloc::difference_type>::value));
271 BOOST_STATIC_ASSERT((
272 boost::is_same<small_container_0::size_type,small_alloc::size_type>::value));
273 BOOST_STATIC_ASSERT((
274 boost::is_same<
275 small_container_0::difference_type,small_alloc::difference_type>::value));
276 BOOST_STATIC_ASSERT((
277 boost::is_same<small_container_1::size_type,small_alloc::size_type>::value));
278 BOOST_STATIC_ASSERT((
279 boost::is_same<
280 small_container_1::difference_type,small_alloc::difference_type>::value));
281 BOOST_STATIC_ASSERT((
282 boost::is_same<small_container_2::size_type,small_alloc::size_type>::value));
283 BOOST_STATIC_ASSERT((
284 boost::is_same<
285 small_container_2::difference_type,small_alloc::difference_type>::value));
286 BOOST_STATIC_ASSERT((
287 boost::is_same<small_container_3::size_type,small_alloc::size_type>::value));
288 BOOST_STATIC_ASSERT((
289 boost::is_same<
290 small_container_3::difference_type,small_alloc::difference_type>::value));
291 BOOST_STATIC_ASSERT((
292 boost::is_same<small_container_4::size_type,small_alloc::size_type>::value));
293 BOOST_STATIC_ASSERT((
294 boost::is_same<
295 small_container_4::difference_type,small_alloc::difference_type>::value));
296
297 small_container sc;
298 small_container_0& sc0=sc.get<0>();
299 small_container_1& sc1=sc.get<1>();
300 small_container_2& sc2=sc.get<2>();
301 small_container_3& sc3=sc.get<3>();
302 small_container_4& sc4=sc.get<4>();
303 small_alloc::size_type s,
304 ms=(small_alloc::size_type)(-1);
305
306 sc.insert(x: 0);
307
308 s=sc0.size();
309 BOOST_TEST(sc0.max_size()<=ms);
310 s=sc0.erase(x: 1);
311 s=sc0.count(x: 0);
312 s=sc0.count(x: 0,comp: std::less<int>());
313
314 s=sc1.size();
315 BOOST_TEST(sc1.max_size()<=ms);
316 s=sc1.erase(x: 1);
317 s=sc1.count(x: 0);
318 s=sc1.count(x: 0,comp: std::less<int>());
319 (void)sc1.nth(n: s);
320 s=sc1.rank(position: sc1.begin());
321 s=sc1.find_rank(x: 0);
322 s=sc1.find_rank(x: 0,comp: std::less<int>());
323 s=sc1.lower_bound_rank(x: 0);
324 s=sc1.lower_bound_rank(x: 0,comp: std::less<int>());
325 s=sc1.upper_bound_rank(x: 0);
326 s=sc1.upper_bound_rank(x: 0,comp: std::less<int>());
327 s=sc1.equal_range_rank(x: 0).first;
328 s=sc1.equal_range_rank(x: 0).second;
329 s=sc1.range_rank(lower: unbounded,upper: unbounded).first;
330 s=sc1.range_rank(lower: unbounded,upper: unbounded).second;
331
332 s=sc2.size();
333 BOOST_TEST(sc2.max_size()<=ms);
334 s=sc2.erase(k: 1);
335 s=sc2.count(k: 0);
336 s=sc2.count(k: 0,hash: boost::hash<int>(),eq: std::equal_to<int>());
337 s=sc2.bucket_count();
338 BOOST_TEST(sc2.max_bucket_count()<=ms);
339 BOOST_TEST(sc2.bucket_size((small_alloc::size_type)(0))<=ms);
340 BOOST_TEST(sc2.bucket_size(0)<=ms);
341 (void)sc2.begin(n: 0);
342 (void)sc2.end(n: 0);
343 (void)sc2.cbegin(n: 0);
344 (void)sc2.cend(n: 0);
345 sc2.rehash(n: 2);
346 sc2.reserve(n: 2);
347
348 s=sc3.size();
349 BOOST_TEST(sc3.max_size()<=ms);
350 sc3.resize(n: 0);
351 sc3.resize(n: 0,x: 0);
352 sc3.assign(n: (small_alloc::size_type)(1),value: 0);
353 sc3.insert(position: sc3.begin(),n: (small_alloc::size_type)(0),x: 0);
354
355 s=sc4.size();
356 BOOST_TEST(sc4.max_size()<=ms);
357 BOOST_TEST(sc4.capacity()<=ms);
358 sc4.reserve(n: 0);
359 sc4.resize(n: 0);
360 sc4.resize(n: 0,x: 0);
361 sc4.assign(n: (small_alloc::size_type)(1),value: 0);
362 (void)sc4[0];
363 (void)sc4.at(n: 0);
364 sc4.insert(position: sc4.begin(),n: (small_alloc::size_type)(0),x: 0);
365}
366

source code of boost/libs/multi_index/test/test_copy_assignment.cpp