1 /* Boost.MultiIndex test for key extractors.
2 *
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)
7 *
8 * See http://www.boost.org/libs/multi_index for library home page.
9 */
10
11 #include "test_key_extractors.hpp"
12
13 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
14 #include <boost/detail/lightweight_test.hpp>
15 #include "pre_multi_index.hpp"
16 #include <boost/multi_index/key_extractors.hpp>
17 #include <boost/ref.hpp>
18 #include <boost/scoped_ptr.hpp>
19 #include <list>
20
21 using namespace boost::multi_index;
22 using namespace boost::tuples;
23
24 struct test_class
25 {
26 int int_member;
27 const int int_cmember;
28
bool_mem_fun_consttest_class29 bool bool_mem_fun_const()const{return true;}
bool_mem_funtest_class30 bool bool_mem_fun(){return false;}
31
bool_global_funtest_class32 static bool bool_global_fun(test_class){return true;}
bool_global_fun_const_reftest_class33 static bool bool_global_fun_const_ref(const test_class&){return false;}
bool_global_fun_reftest_class34 static bool bool_global_fun_ref(test_class&){return true;}
35
test_classtest_class36 test_class(int i=0):int_member(i),int_cmember(i){}
test_classtest_class37 test_class(int i,int j):int_member(i),int_cmember(j){}
38
operator =test_class39 test_class& operator=(const test_class& x)
40 {
41 int_member=x.int_member;
42 return *this;
43 }
44
operator <test_class45 bool operator<(const test_class& x)const
46 {
47 if(int_member<x.int_member)return true;
48 if(x.int_member<int_member)return false;
49 return int_cmember<x.int_cmember;
50 }
51
operator ==test_class52 bool operator==(const test_class& x)const
53 {
54 return int_member==x.int_member&&int_cmember==x.int_cmember;
55 }
56 };
57
58 struct test_derived_class:test_class
59 {
test_derived_classtest_derived_class60 test_derived_class(int i=0):test_class(i){}
test_derived_classtest_derived_class61 test_derived_class(int i,int j):test_class(i,j){}
62 };
63
64 typedef identity<test_class> idn;
65 typedef identity<const test_class> cidn;
66 typedef BOOST_MULTI_INDEX_MEMBER(test_class,int,int_member) key_m;
67 typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_member) ckey_m;
68 typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_cmember) key_cm;
69 typedef BOOST_MULTI_INDEX_CONST_MEM_FUN(
70 test_class,bool,bool_mem_fun_const) key_cmf;
71 typedef BOOST_MULTI_INDEX_MEM_FUN(test_class,bool,bool_mem_fun) key_mf;
72 typedef global_fun<test_class,bool,&test_class::bool_global_fun> key_gf;
73 typedef global_fun<
74 const test_class&,bool,
75 &test_class::bool_global_fun_const_ref
76 > key_gcrf;
77 typedef global_fun<
78 test_class&,bool,
79 &test_class::bool_global_fun_ref
80 > key_grf;
81 typedef composite_key<
82 test_class,
83 idn,
84 key_m,
85 key_cm,
86 key_cmf
87 > compkey;
88 typedef composite_key<
89 test_class,
90 cidn,
91 ckey_m
92 > ccompkey;
93 typedef composite_key<
94 boost::reference_wrapper<test_class>,
95 key_mf
96 > ccompw_key;
97
98 #if !defined(BOOST_NO_SFINAE)
99 /* testcases for problems with non-copyable classes reported at
100 * http://lists.boost.org/Archives/boost/2006/04/103065.php
101 */
102
103 struct test_nc_class
104 {
105 int int_member;
106 const int int_cmember;
107
bool_mem_fun_consttest_nc_class108 bool bool_mem_fun_const()const{return true;}
bool_mem_funtest_nc_class109 bool bool_mem_fun(){return false;}
110
bool_global_fun_const_reftest_nc_class111 static bool bool_global_fun_const_ref(const test_nc_class&){return false;}
bool_global_fun_reftest_nc_class112 static bool bool_global_fun_ref(test_nc_class&){return true;}
113
test_nc_classtest_nc_class114 test_nc_class(int i=0):int_member(i),int_cmember(i){}
test_nc_classtest_nc_class115 test_nc_class(int i,int j):int_member(i),int_cmember(j){}
116
operator ==test_nc_class117 bool operator==(const test_nc_class& x)const
118 {
119 return int_member==x.int_member&&int_cmember==x.int_cmember;
120 }
121
122 private:
123 test_nc_class(const test_nc_class&);
124 test_nc_class& operator=(const test_nc_class&);
125 };
126
127 struct test_nc_derived_class:test_nc_class
128 {
test_nc_derived_classtest_nc_derived_class129 test_nc_derived_class(int i=0):test_nc_class(i){}
test_nc_derived_classtest_nc_derived_class130 test_nc_derived_class(int i,int j):test_nc_class(i,j){}
131 };
132
133 typedef identity<test_nc_class> nc_idn;
134 typedef identity<const test_nc_class> nc_cidn;
135 typedef BOOST_MULTI_INDEX_MEMBER(test_nc_class,int,int_member) nc_key_m;
136 typedef BOOST_MULTI_INDEX_MEMBER(
137 test_nc_class,const int,int_member) nc_ckey_m;
138 typedef BOOST_MULTI_INDEX_CONST_MEM_FUN(
139 test_nc_class,bool,bool_mem_fun_const) nc_key_cmf;
140 typedef BOOST_MULTI_INDEX_MEM_FUN(
141 test_nc_class,bool,bool_mem_fun) nc_key_mf;
142 typedef global_fun<
143 const test_nc_class&,bool,
144 &test_nc_class::bool_global_fun_const_ref
145 > nc_key_gcrf;
146 typedef global_fun<
147 test_nc_class&,bool,
148 &test_nc_class::bool_global_fun_ref
149 > nc_key_grf;
150 typedef composite_key<
151 test_nc_class,
152 nc_idn,
153 nc_key_m,
154 nc_ckey_m,
155 nc_key_cmf
156 > nc_compkey;
157 #endif
158
test_key_extractors()159 void test_key_extractors()
160 {
161 idn id;
162 cidn cid;
163 key_m k_m;
164 ckey_m ck_m;
165 key_cm k_cm;
166 key_cmf k_cmf;
167 key_mf k_mf;
168 key_gf k_gf;
169 key_gcrf k_gcrf;
170 key_grf k_grf;
171 compkey cmpk;
172 ccompkey ccmpk;
173 ccompw_key ccmpk_w;
174
175 test_derived_class td(-1,0);
176 const test_derived_class& ctdr=td;
177
178 test_class& tr=td;
179 const test_class& ctr=tr;
180
181 test_derived_class* tdp=&td;
182 const test_derived_class* ctdp=&ctdr;
183
184 test_class* tp=&tr;
185 const test_class* ctp=&tr;
186
187 test_class** tpp=&tp;
188 const test_class** ctpp=&ctp;
189
190 boost::scoped_ptr<test_class*> tap(new test_class*(tp));
191 boost::scoped_ptr<const test_class*> ctap(new const test_class*(ctp));
192
193 boost::reference_wrapper<test_class> tw(tr);
194 boost::reference_wrapper<const test_class> ctw(tr);
195
196 id(tr).int_member=0;
197 BOOST_TEST(id(tr).int_member==0);
198 BOOST_TEST(cid(tr).int_member==0);
199 BOOST_TEST(k_m(tr)==0);
200 BOOST_TEST(ck_m(tr)==0);
201 BOOST_TEST(cmpk(tr)==make_tuple(test_class(0,0),0,0,true));
202 BOOST_TEST(ccmpk(tr)==make_tuple(test_class(0,0),0));
203 BOOST_TEST(id(ctr).int_member==0);
204 BOOST_TEST(cid(ctr).int_member==0);
205 BOOST_TEST(k_m(ctr)==0);
206 BOOST_TEST(ck_m(ctr)==0);
207 BOOST_TEST(cmpk(ctr)==make_tuple(test_class(0,0),0,0,true));
208 BOOST_TEST(ccmpk(ctr)==make_tuple(test_class(0,0),0));
209
210 #if !defined(BOOST_NO_SFINAE)
211 BOOST_TEST(id(td).int_member==0);
212 BOOST_TEST(cid(td).int_member==0);
213 BOOST_TEST(k_m(td)==0);
214 BOOST_TEST(ck_m(td)==0);
215 BOOST_TEST(cmpk(td)==make_tuple(test_class(0,0),0,0,true));
216 BOOST_TEST(ccmpk(td)==make_tuple(test_class(0,0),0));
217 BOOST_TEST(id(ctdr).int_member==0);
218 BOOST_TEST(cid(ctdr).int_member==0);
219 BOOST_TEST(k_m(ctdr)==0);
220 BOOST_TEST(ck_m(ctdr)==0);
221 BOOST_TEST(cmpk(ctdr)==make_tuple(test_class(0,0),0,0,true));
222 BOOST_TEST(ccmpk(ctdr)==make_tuple(test_class(0,0),0));
223 #endif
224
225 k_m(tr)=1;
226 BOOST_TEST(id(tp).int_member==1);
227 BOOST_TEST(cid(tp).int_member==1);
228 BOOST_TEST(k_m(tp)==1);
229 BOOST_TEST(ck_m(tp)==1);
230 BOOST_TEST(cmpk(tp)==make_tuple(test_class(1,0),1,0,true));
231 BOOST_TEST(ccmpk(tp)==make_tuple(test_class(1,0),1));
232 BOOST_TEST(cid(ctp).int_member==1);
233 BOOST_TEST(ck_m(ctp)==1);
234 BOOST_TEST(cmpk(ctp)==make_tuple(test_class(1,0),1,0,true));
235 BOOST_TEST(ccmpk(ctp)==make_tuple(test_class(1,0),1));
236
237 #if !defined(BOOST_NO_SFINAE)
238 BOOST_TEST(id(tdp).int_member==1);
239 BOOST_TEST(cid(tdp).int_member==1);
240 BOOST_TEST(k_m(tdp)==1);
241 BOOST_TEST(ck_m(tdp)==1);
242 BOOST_TEST(cmpk(tdp)==make_tuple(test_class(1,0),1,0,true));
243 BOOST_TEST(ccmpk(tdp)==make_tuple(test_class(1,0),1));
244 BOOST_TEST(cid(ctdp).int_member==1);
245 BOOST_TEST(ck_m(ctdp)==1);
246 BOOST_TEST(cmpk(ctdp)==make_tuple(test_class(1,0),1,0,true));
247 BOOST_TEST(ccmpk(ctdp)==make_tuple(test_class(1,0),1));
248 #endif
249
250 k_m(tp)=2;
251 BOOST_TEST(id(tpp).int_member==2);
252 BOOST_TEST(cid(tpp).int_member==2);
253 BOOST_TEST(k_m(tpp)==2);
254 BOOST_TEST(ck_m(tpp)==2);
255 BOOST_TEST(cmpk(tpp)==make_tuple(test_class(2,0),2,0,true));
256 BOOST_TEST(ccmpk(tpp)==make_tuple(test_class(2,0),2));
257 BOOST_TEST(cid(ctpp).int_member==2);
258 BOOST_TEST(ck_m(ctpp)==2);
259 BOOST_TEST(cmpk(ctpp)==make_tuple(test_class(2,0),2,0,true));
260 BOOST_TEST(ccmpk(ctpp)==make_tuple(test_class(2,0),2));
261
262 k_m(tpp)=3;
263 BOOST_TEST(id(tap).int_member==3);
264 BOOST_TEST(cid(tap).int_member==3);
265 BOOST_TEST(k_m(tap)==3);
266 BOOST_TEST(ck_m(tap)==3);
267 BOOST_TEST(cmpk(tap)==make_tuple(test_class(3,0),3,0,true));
268 BOOST_TEST(ccmpk(tap)==make_tuple(test_class(3,0),3));
269 BOOST_TEST(cid(ctap).int_member==3);
270 BOOST_TEST(ck_m(ctap)==3);
271 BOOST_TEST(cmpk(ctap)==make_tuple(test_class(3,0),3,0,true));
272 BOOST_TEST(ccmpk(ctap)==make_tuple(test_class(3,0),3));
273
274 k_m(tap)=4;
275 BOOST_TEST(id(tw).int_member==4);
276 BOOST_TEST(cid(tw).int_member==4);
277 BOOST_TEST(k_m(tw)==4);
278 BOOST_TEST(ck_m(tw)==4);
279 BOOST_TEST(cmpk(tw)==make_tuple(test_class(4,0),4,0,true));
280 BOOST_TEST(ccmpk(tw)==make_tuple(test_class(4,0),4));
281
282 k_m(tw)=5;
283 BOOST_TEST(id(ctw).int_member==5);
284 BOOST_TEST(cid(ctw).int_member==5);
285 BOOST_TEST(k_m(ctw)==5);
286 BOOST_TEST(ck_m(ctw)==5);
287 BOOST_TEST(cmpk(ctw)==make_tuple(test_class(5,0),5,0,true));
288 BOOST_TEST(ccmpk(ctw)==make_tuple(test_class(5,0),5));
289
290 BOOST_TEST(k_cm(tr)==0);
291 BOOST_TEST(k_cm(ctr)==0);
292
293 #if !defined(BOOST_NO_SFINAE)
294 BOOST_TEST(k_cm(td)==0);
295 BOOST_TEST(k_cm(ctdr)==0);
296 #endif
297
298 BOOST_TEST(k_cm(tp)==0);
299 BOOST_TEST(k_cm(ctp)==0);
300
301 #if !defined(BOOST_NO_SFINAE)
302 BOOST_TEST(k_cm(tdp)==0);
303 BOOST_TEST(k_cm(ctdp)==0);
304 #endif
305
306 BOOST_TEST(k_cm(tpp)==0);
307 BOOST_TEST(k_cm(ctpp)==0);
308 BOOST_TEST(k_cm(tap)==0);
309 BOOST_TEST(k_cm(ctap)==0);
310
311 BOOST_TEST(k_cm(tw)==0);
312 BOOST_TEST(k_cm(ctw)==0);
313
314 BOOST_TEST(k_cmf(tr));
315 BOOST_TEST(k_cmf(ctr));
316
317 #if !defined(BOOST_NO_SFINAE)
318 BOOST_TEST(k_cmf(td));
319 BOOST_TEST(k_cmf(ctdr));
320 #endif
321
322 BOOST_TEST(k_cmf(tp));
323 BOOST_TEST(k_cmf(ctp));
324
325 #if !defined(BOOST_NO_SFINAE)
326 BOOST_TEST(k_cmf(tdp));
327 BOOST_TEST(k_cmf(ctdp));
328 #endif
329
330 BOOST_TEST(k_cmf(tpp));
331 BOOST_TEST(k_cmf(ctpp));
332 BOOST_TEST(k_cmf(tap));
333 BOOST_TEST(k_cmf(ctap));
334
335 BOOST_TEST(k_cmf(tw));
336 BOOST_TEST(k_cmf(ctw));
337
338 BOOST_TEST(!k_mf(tr));
339
340 #if !defined(BOOST_NO_SFINAE)
341 BOOST_TEST(!k_mf(td));
342 #endif
343
344 BOOST_TEST(!k_mf(tp));
345
346 #if !defined(BOOST_NO_SFINAE)
347 BOOST_TEST(!k_mf(tdp));
348 #endif
349
350 BOOST_TEST(!k_mf(tpp));
351 BOOST_TEST(!k_mf(tap));
352 BOOST_TEST(!k_mf(tw));
353
354 BOOST_TEST(k_gf(tr));
355 BOOST_TEST(k_gf(ctr));
356
357 #if !defined(BOOST_NO_SFINAE)
358 BOOST_TEST(k_gf(td));
359 BOOST_TEST(k_gf(ctdr));
360 #endif
361
362 BOOST_TEST(k_gf(tp));
363 BOOST_TEST(k_gf(ctp));
364
365 #if !defined(BOOST_NO_SFINAE)
366 BOOST_TEST(k_gf(tdp));
367 BOOST_TEST(k_gf(ctdp));
368 #endif
369
370 BOOST_TEST(k_gf(tpp));
371 BOOST_TEST(k_gf(ctpp));
372 BOOST_TEST(k_gf(tap));
373 BOOST_TEST(k_gf(ctap));
374
375 BOOST_TEST(k_gf(tw));
376 BOOST_TEST(k_gf(ctw));
377
378 BOOST_TEST(!k_gcrf(tr));
379 BOOST_TEST(!k_gcrf(ctr));
380
381 #if !defined(BOOST_NO_SFINAE)
382 BOOST_TEST(!k_gcrf(td));
383 BOOST_TEST(!k_gcrf(ctdr));
384 #endif
385
386 BOOST_TEST(!k_gcrf(tp));
387 BOOST_TEST(!k_gcrf(ctp));
388
389 #if !defined(BOOST_NO_SFINAE)
390 BOOST_TEST(!k_gcrf(tdp));
391 BOOST_TEST(!k_gcrf(ctdp));
392 #endif
393
394 BOOST_TEST(!k_gcrf(tpp));
395 BOOST_TEST(!k_gcrf(ctpp));
396 BOOST_TEST(!k_gcrf(tap));
397 BOOST_TEST(!k_gcrf(ctap));
398
399 BOOST_TEST(!k_gcrf(tw));
400 BOOST_TEST(!k_gcrf(ctw));
401
402 BOOST_TEST(k_grf(tr));
403
404 #if !defined(BOOST_NO_SFINAE)
405 BOOST_TEST(k_grf(td));
406 #endif
407
408 BOOST_TEST(k_grf(tp));
409
410 #if !defined(BOOST_NO_SFINAE)
411 BOOST_TEST(k_grf(tdp));
412 #endif
413
414 BOOST_TEST(k_grf(tpp));
415 BOOST_TEST(k_grf(tap));
416 BOOST_TEST(k_grf(tw));
417
418 BOOST_TEST(ccmpk_w(tw)==make_tuple(false));
419
420 #if !defined(BOOST_NO_SFINAE)
421 /* testcases for problems with non-copyable classes reported at
422 * http://lists.boost.org/Archives/boost/2006/04/103065.php
423 */
424
425 nc_idn nc_id;
426 nc_cidn nc_cid;
427 nc_key_m nc_k_m;
428 nc_ckey_m nc_ck_m;
429 nc_key_cmf nc_k_cmf;
430 nc_key_mf nc_k_mf;
431 nc_key_gcrf nc_k_gcrf;
432 nc_key_grf nc_k_grf;
433 nc_compkey nc_cmpk;
434
435 test_nc_derived_class nc_td(-1,0);
436
437 nc_id(nc_td).int_member=0;
438 BOOST_TEST(nc_id(nc_td).int_member==0);
439 BOOST_TEST(nc_cid(nc_td).int_member==0);
440
441 nc_k_m(&nc_td)=1;
442 BOOST_TEST(nc_k_m(&nc_td)==1);
443 BOOST_TEST(nc_ck_m(&nc_td)==1);
444
445 BOOST_TEST(nc_k_cmf(nc_td));
446 BOOST_TEST(!nc_k_mf(nc_td));
447
448 BOOST_TEST(!nc_k_gcrf(nc_td));
449 BOOST_TEST(nc_k_grf(nc_td));
450
451 test_nc_class nc_t(1,0);
452 BOOST_TEST(nc_cmpk(nc_td)==make_tuple(boost::cref(nc_t),1,1,true));
453 #endif
454
455 std::list<test_class> tl;
456 for(int i=0;i<20;++i)tl.push_back(test_class(i));
457
458 int j=0;
459 for(std::list<test_class>::iterator it=tl.begin();it!=tl.end();++it){
460 BOOST_TEST(k_m(it)==j);
461 BOOST_TEST(k_cm(it)==j);
462 BOOST_TEST(k_cmf(it));
463 BOOST_TEST(!k_mf(it));
464 BOOST_TEST(k_gf(it));
465 BOOST_TEST(!k_gcrf(it));
466 BOOST_TEST(k_grf(it));
467 BOOST_TEST(cmpk(it)==make_tuple(test_class(j),j,j,true));
468 BOOST_TEST(ccmpk(it)==make_tuple(test_class(j),j));
469 ++j;
470 }
471 }
472