• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 using 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 
35 typedef multi_index_container<int> copyable_and_movable;
36 
37 struct holder
38 {
39   copyable_and_movable c;
40 };
41 
42 template<typename Sequence>
test_assign()43 static 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 
75 template<typename Sequence>
test_integral_assign()76 static 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 
produce_employee_set()96 employee_set produce_employee_set()
97 {
98   employee_set es;
99   es.insert(employee(0,"Petr",60,2837));
100   es.insert(employee(1,"Jiri",25,2143));
101   es.insert(employee(2,"Radka",40,4875));
102   es.insert(employee(3,"Milan",38,3474));
103   return es;
104 }
105 
test_copy_assignment()106 void 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>(es).get_allocator();
113   al=get<2>(es).get_allocator();
114   al=get<3>(es).get_allocator();
115   al=get<4>(es).get_allocator();
116   al=get<5>(es).get_allocator();
117 
118   BOOST_TEST(es2.empty());
119 
120   es2.insert(employee(0,"Joe",31,1123));
121   es2.insert(employee(1,"Robert",27,5601));
122   es2.insert(employee(2,"John",40,7889));
123   es2.insert(employee(2,"Aristotle",2388,3357)); /* clash */
124   es2.insert(employee(3,"Albert",20,9012));
125   es2.insert(employee(4,"John",57,1002));
126   es2.insert(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>(es4);
137   i1=get<1>(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>(es5);
143   i2=get<2>(es2);
144 
145   BOOST_TEST(i2==get<2>(es2));
146 
147   employee_set es6;
148   employee_set_as_inserted& i3=get<as_inserted>(es6);
149   i3=get<3>(es2);
150 
151   BOOST_TEST(i3==get<3>(es2));
152 
153   employee_set es7;
154   employee_set_randomly& i5=get<randomly>(es7);
155   i5=get<5>(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>(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>(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>(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>(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>(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>(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>(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(es10));
206   BOOST_TEST(es10.empty());
207   BOOST_TEST(es11==es12);
208 
209   es10=boost::move(es12);
210   BOOST_TEST(es12.empty());
211   BOOST_TEST(es11==es10);
212 
213   std::list<employee> l;
214   l.push_back(employee(3,"Anna",31,5388));
215   l.push_back(employee(1,"Rachel",27,9012));
216   l.push_back(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(0);
307 
308   s=sc0.size();
309   BOOST_TEST(sc0.max_size()<=ms);
310   s=sc0.erase(1);
311   s=sc0.count(0);
312   s=sc0.count(0,std::less<int>());
313 
314   s=sc1.size();
315   BOOST_TEST(sc1.max_size()<=ms);
316   s=sc1.erase(1);
317   s=sc1.count(0);
318   s=sc1.count(0,std::less<int>());
319   (void)sc1.nth(s);
320   s=sc1.rank(sc1.begin());
321   s=sc1.find_rank(0);
322   s=sc1.find_rank(0,std::less<int>());
323   s=sc1.lower_bound_rank(0);
324   s=sc1.lower_bound_rank(0,std::less<int>());
325   s=sc1.upper_bound_rank(0);
326   s=sc1.upper_bound_rank(0,std::less<int>());
327   s=sc1.equal_range_rank(0).first;
328   s=sc1.equal_range_rank(0).second;
329   s=sc1.range_rank(unbounded,unbounded).first;
330   s=sc1.range_rank(unbounded,unbounded).second;
331 
332   s=sc2.size();
333   BOOST_TEST(sc2.max_size()<=ms);
334   s=sc2.erase(1);
335   s=sc2.count(0);
336   s=sc2.count(0,boost::hash<int>(),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(0);
342   (void)sc2.end(0);
343   (void)sc2.cbegin(0);
344   (void)sc2.cend(0);
345   sc2.rehash(2);
346   sc2.reserve(2);
347 
348   s=sc3.size();
349   BOOST_TEST(sc3.max_size()<=ms);
350   sc3.resize(0);
351   sc3.resize(0,0);
352   sc3.assign((small_alloc::size_type)(1),0);
353   sc3.insert(sc3.begin(),(small_alloc::size_type)(0),0);
354 
355   s=sc4.size();
356   BOOST_TEST(sc4.max_size()<=ms);
357   BOOST_TEST(sc4.capacity()<=ms);
358   sc4.reserve(0);
359   sc4.resize(0);
360   sc4.resize(0,0);
361   sc4.assign((small_alloc::size_type)(1),0);
362   (void)sc4[0];
363   (void)sc4.at(0);
364   sc4.insert(sc4.begin(),(small_alloc::size_type)(0),0);
365 }
366