1/* Boost.MultiIndex test for composite_key.
2 *
3 * Copyright 2003-2021 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_composite_key.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_container.hpp>
17#include <boost/multi_index/composite_key.hpp>
18#include <boost/multi_index/hashed_index.hpp>
19#include <boost/multi_index/member.hpp>
20#include <boost/multi_index/ordered_index.hpp>
21#include <boost/preprocessor/repetition/enum_binary_params.hpp>
22#include <boost/preprocessor/repetition/enum_params.hpp>
23#include <boost/preprocessor/repetition/repeat_from_to.hpp>
24
25using namespace boost::multi_index;
26using namespace boost::tuples;
27
28struct is_composite_key_result_helper
29{
30 typedef char yes;
31 struct no{char m[2];};
32
33 static no test(void*);
34
35 template<typename CompositeKey>
36 static yes test(composite_key_result<CompositeKey>*);
37};
38
39template<typename T>
40struct is_composite_key_result
41{
42 typedef is_composite_key_result_helper helper;
43
44 BOOST_STATIC_CONSTANT(bool,
45 value=(
46 sizeof(helper::test((T*)0))==
47 sizeof(typename helper::yes)));
48};
49
50template<typename CompositeKeyResult>
51struct composite_key_result_length
52{
53 BOOST_STATIC_CONSTANT(int,
54 value=boost::tuples::length<
55 BOOST_DEDUCED_TYPENAME
56 CompositeKeyResult::composite_key_type::key_extractor_tuple
57 >::value);
58};
59
60#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
61 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
62struct is_boost_tuple_helper
63{
64 typedef char yes;
65 struct no{char m[2];};
66
67 static no test(void*);
68
69 template<BOOST_PP_ENUM_PARAMS(10,typename T)>
70 static yes test(boost::tuple<BOOST_PP_ENUM_PARAMS(10,T)>*);
71};
72
73template<typename T>
74struct is_boost_tuple
75{
76 typedef is_boost_tuple_helper helper;
77
78 BOOST_STATIC_CONSTANT(bool,
79 value=(
80 sizeof(helper::test((T*)0))==
81 sizeof(typename helper::yes)));
82};
83
84template<typename T>
85struct composite_object_length
86{
87 typedef typename boost::mpl::if_c<
88 is_composite_key_result<T>::value,
89 composite_key_result_length<T>,
90 typename boost::mpl::if_c<
91 is_boost_tuple<T>::value,
92 boost::tuples::length<T>,
93 std::tuple_size<T>
94 >::type
95 >::type type;
96
97 BOOST_STATIC_CONSTANT(int,value=type::value);
98};
99#else
100template<typename T>
101struct composite_object_length
102{
103 typedef typename boost::mpl::if_c<
104 is_composite_key_result<T>::value,
105 composite_key_result_length<T>,
106 boost::tuples::length<T>
107 >::type type;
108
109 BOOST_STATIC_CONSTANT(int,value=type::value);
110};
111#endif
112
113template<typename CompositeKeyResult,typename T2>
114struct comparison_equal_length
115{
116 static bool is_less(const CompositeKeyResult& x,const T2& y)
117 {
118 composite_key_result_equal_to<CompositeKeyResult> eq;
119 composite_key_result_less<CompositeKeyResult> lt;
120 composite_key_result_greater<CompositeKeyResult> gt;
121 std::equal_to<CompositeKeyResult> std_eq;
122 std::less<CompositeKeyResult> std_lt;
123 std::greater<CompositeKeyResult> std_gt;
124
125 return (x< y) && !(y< x)&&
126 !(x==y) && !(y==x)&&
127 (x!=y) && (y!=x)&&
128 !(x> y) && (y> x)&&
129 !(x>=y) && (y>=x)&&
130 (x<=y) && !(y<=x)&&
131 !eq(x,y) && !eq(y,x)&&
132 lt(x,y) && !lt(y,x)&&
133 !gt(x,y) && gt(y,x)&&
134 !std_eq(x,y) && !std_eq(y,x)&&
135 std_lt(x,y) && !std_lt(y,x)&&
136 !std_gt(x,y) && std_gt(y,x);
137 }
138
139 static bool is_greater(const CompositeKeyResult& x,const T2& y)
140 {
141 composite_key_result_equal_to<CompositeKeyResult> eq;
142 composite_key_result_less<CompositeKeyResult> lt;
143 composite_key_result_greater<CompositeKeyResult> gt;
144 std::equal_to<CompositeKeyResult> std_eq;
145 std::less<CompositeKeyResult> std_lt;
146 std::greater<CompositeKeyResult> std_gt;
147
148 return !(x< y) && (y< x)&&
149 !(x==y) && !(y==x)&&
150 (x!=y) && (y!=x)&&
151 (x> y) && !(y> x)&&
152 (x>=y) && !(y>=x)&&
153 !(x<=y) && (y<=x)&&
154 !eq(x,y) && !eq(y,x)&&
155 !lt(x,y) && lt(y,x)&&
156 gt(x,y) && !gt(y,x)&&
157 !std_eq(x,y) && !std_eq(y,x)&&
158 !std_lt(x,y) && std_lt(y,x)&&
159 std_gt(x,y) && !std_gt(y,x);
160 }
161
162 static bool is_equiv(const CompositeKeyResult& x,const T2& y)
163 {
164 composite_key_result_equal_to<CompositeKeyResult> eq;
165 composite_key_result_less<CompositeKeyResult> lt;
166 composite_key_result_greater<CompositeKeyResult> gt;
167 std::equal_to<CompositeKeyResult> std_eq;
168 std::less<CompositeKeyResult> std_lt;
169 std::greater<CompositeKeyResult> std_gt;
170
171 return !(x< y) && !(y< x)&&
172 (x==y) && (y==x)&&
173 !(x!=y) && !(y!=x)&&
174 !(x> y) && !(y> x)&&
175 (x>=y) && (y>=x)&&
176 (x<=y) && (y<=x)&&
177 eq(x,y) && eq(y,x)&&
178 !lt(x,y) && !lt(y,x)&&
179 !gt(x,y) && !gt(y,x)&&
180 std_eq(x,y) && std_eq(y,x)&&
181 !std_lt(x,y) && !std_lt(y,x)&&
182 !std_gt(x,y) && !std_gt(y,x);
183 }
184};
185
186template<typename CompositeKeyResult,typename T2>
187struct comparison_different_length
188{
189 static bool is_less(const CompositeKeyResult& x,const T2& y)
190 {
191 composite_key_result_less<CompositeKeyResult> lt;
192 composite_key_result_greater<CompositeKeyResult> gt;
193 std::less<CompositeKeyResult> std_lt;
194 std::greater<CompositeKeyResult> std_gt;
195
196 return (x< y) && !(y< x)&&
197 !(x> y) && (y> x)&&
198 !(x>=y) && (y>=x)&&
199 (x<=y) && !(y<=x)&&
200 lt(x,y) && !lt(y,x)&&
201 !gt(x,y) && gt(y,x)&&
202 std_lt(x,y) && !std_lt(y,x)&&
203 !std_gt(x,y) && std_gt(y,x);
204 }
205
206 static bool is_greater(const CompositeKeyResult& x,const T2& y)
207 {
208 composite_key_result_less<CompositeKeyResult> lt;
209 composite_key_result_greater<CompositeKeyResult> gt;
210 std::less<CompositeKeyResult> std_lt;
211 std::greater<CompositeKeyResult> std_gt;
212
213 return !(x< y) && (y< x)&&
214 (x> y) && !(y> x)&&
215 (x>=y) && !(y>=x)&&
216 !(x<=y) && (y<=x)&&
217 !lt(x,y) && lt(y,x)&&
218 gt(x,y) && !gt(y,x)&&
219 !std_lt(x,y) && std_lt(y,x)&&
220 std_gt(x,y) && !std_gt(y,x);
221 }
222
223 static bool is_equiv(const CompositeKeyResult& x,const T2& y)
224 {
225 composite_key_result_less<CompositeKeyResult> lt;
226 composite_key_result_greater<CompositeKeyResult> gt;
227 std::less<CompositeKeyResult> std_lt;
228 std::greater<CompositeKeyResult> std_gt;
229
230 return !(x< y) && !(y< x)&&
231 !(x> y) && !(y> x)&&
232 (x>=y) && (y>=x)&&
233 (x<=y) && (y<=x)&&
234 !lt(x,y) && !lt(y,x)&&
235 !gt(x,y) && !gt(y,x)&&
236 !std_lt(x,y) && !std_lt(y,x)&&
237 !std_gt(x,y) && !std_gt(y,x);
238 }
239};
240
241template<typename CompositeKeyResult,typename T2>
242struct comparison_helper:
243 boost::mpl::if_c<
244 composite_key_result_length<CompositeKeyResult>::value==
245 composite_object_length<T2>::value,
246 comparison_equal_length<CompositeKeyResult,T2>,
247 comparison_different_length<CompositeKeyResult,T2>
248 >::type
249{
250};
251
252template<typename CompositeKeyResult,typename T2>
253static bool is_less(const CompositeKeyResult& x,const T2& y)
254{
255 return comparison_helper<CompositeKeyResult,T2>::is_less(x,y);
256}
257
258template<typename CompositeKeyResult,typename T2>
259static bool is_greater(const CompositeKeyResult& x,const T2& y)
260{
261 return comparison_helper<CompositeKeyResult,T2>::is_greater(x,y);
262}
263
264template<typename CompositeKeyResult,typename T2>
265static bool is_equiv(const CompositeKeyResult& x,const T2& y)
266{
267 return comparison_helper<CompositeKeyResult,T2>::is_equiv(x,y);
268}
269
270template<typename T1,typename T2,typename Compare>
271static bool is_less(const T1& x,const T2& y,const Compare& c)
272{
273 return c(x,y)&&!c(y,x);
274}
275
276template<typename T1,typename T2,typename Compare>
277static bool is_greater(const T1& x,const T2& y,const Compare& c)
278{
279 return c(y,x)&&!c(x,y);
280}
281
282template<typename T1,typename T2,typename Compare>
283static bool is_equiv(const T1& x,const T2& y,const Compare& c)
284{
285 return !c(x,y)&&!c(y,x);
286}
287
288template<typename T1,typename T2,typename Compare,typename Equiv>
289static bool is_less(
290 const T1& x,const T2& y,const Compare& c,const Equiv& eq)
291{
292 return c(x,y)&&!c(y,x)&&!eq(x,y)&&!eq(y,x);
293}
294
295template<typename T1,typename T2,typename Compare,typename Equiv>
296static bool is_greater(
297 const T1& x,const T2& y,const Compare& c,const Equiv& eq)
298{
299 return c(y,x)&&!c(x,y)&&!eq(x,y)&&!eq(y,x);
300}
301
302template<typename T1,typename T2,typename Compare,typename Equiv>
303static bool is_equiv(
304 const T1& x,const T2& y,const Compare& c,const Equiv& eq)
305{
306 return !c(x,y)&&!c(y,x)&&eq(x,y)&&eq(y,x);
307}
308
309struct xyz
310{
311 xyz(int x_=0,int y_=0,int z_=0):x(x_),y(y_),z(z_){}
312
313 int x;
314 int y;
315 int z;
316};
317
318struct modulo_equal
319{
320 modulo_equal(int i):i_(i){}
321 bool operator ()(int x,int y)const{return (x%i_)==(y%i_);}
322
323private:
324 int i_;
325};
326
327struct xystr
328{
329 xystr(int x_=0,int y_=0,std::string str_=""):x(x_),y(y_),str(str_){}
330
331 int x;
332 int y;
333 std::string str;
334};
335
336#define TUPLE_MAKER_CREATE(z,n,tuple) \
337template<BOOST_PP_ENUM_PARAMS(n,typename T)> \
338static tuple<BOOST_PP_ENUM_PARAMS(n,T)> \
339create(BOOST_PP_ENUM_BINARY_PARAMS(n,const T,& t)){ \
340 return tuple<BOOST_PP_ENUM_PARAMS(n,T)>( \
341 BOOST_PP_ENUM_PARAMS(n,t)); \
342}
343
344#define DEFINE_TUPLE_MAKER(name,tuple) \
345struct name \
346{ \
347 static tuple<> create(){return tuple<>();} \
348 BOOST_PP_REPEAT_FROM_TO(1,5,TUPLE_MAKER_CREATE,tuple) \
349};
350
351DEFINE_TUPLE_MAKER(boost_tuple_maker,boost::tuple)
352
353#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
354 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
355DEFINE_TUPLE_MAKER(std_tuple_maker,std::tuple)
356#endif
357
358#undef DEFINE_TUPLE_MAKER
359#undef TUPLE_MAKER_CREATE
360
361template<typename TupleMaker>
362void test_composite_key_template()
363{
364 typedef composite_key<
365 xyz,
366 BOOST_MULTI_INDEX_MEMBER(xyz,int,x),
367 BOOST_MULTI_INDEX_MEMBER(xyz,int,y),
368 BOOST_MULTI_INDEX_MEMBER(xyz,int,z)
369 > ckey_t1;
370
371 typedef multi_index_container<
372 xyz,
373 indexed_by<
374 ordered_unique<ckey_t1>
375 >
376 > indexed_t1;
377
378 indexed_t1 mc1;
379 mc1.insert(x: xyz(0,0,0));
380 mc1.insert(x: xyz(0,0,1));
381 mc1.insert(x: xyz(0,1,0));
382 mc1.insert(x: xyz(0,1,1));
383 mc1.insert(x: xyz(1,0,0));
384 mc1.insert(x: xyz(1,0,1));
385 mc1.insert(x: xyz(1,1,0));
386 mc1.insert(x: xyz(1,1,1));
387
388 BOOST_TEST(mc1.size()==8);
389 BOOST_TEST(
390 std::distance(
391 mc1.find(mc1.key_extractor()(xyz(0,0,0))),
392 mc1.find(mc1.key_extractor()(xyz(1,0,0))))==4);
393 BOOST_TEST(
394 std::distance(
395 mc1.find(TupleMaker::create(0,0,0)),
396 mc1.find(TupleMaker::create(1,0,0)))==4);
397 BOOST_TEST(
398 std::distance(
399 mc1.lower_bound(TupleMaker::create(0,0)),
400 mc1.upper_bound(TupleMaker::create(1,0)))==6);
401
402#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
403 BOOST_TEST(
404 std::distance(
405 mc1.lower_bound(1),
406 mc1.upper_bound(1))==4);
407#endif
408
409 ckey_t1 ck1;
410 ckey_t1 ck2(ck1);
411 ckey_t1 ck3(
412 boost::make_tuple(
413 BOOST_MULTI_INDEX_MEMBER(xyz,int,x)(),
414 BOOST_MULTI_INDEX_MEMBER(xyz,int,y)(),
415 BOOST_MULTI_INDEX_MEMBER(xyz,int,z)()));
416 ckey_t1 ck4(get<0>(c&: ck1.key_extractors()));
417
418 (void)ck3; /* prevent unused var */
419
420 get<2>(c&: ck4.key_extractors())=
421 get<2>(c&: ck2.key_extractors());
422
423 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0))));
424 BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0))));
425 BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0))));
426
427 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0)));
428 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1)));
429 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1)));
430 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0)));
431 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,1)));
432 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,-1)));
433 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0)));
434 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1)));
435 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1)));
436 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0,1)));
437
438 typedef composite_key_result_less<ckey_t1::result_type> ckey_comp_t1;
439 typedef composite_key_result_equal_to<ckey_t1::result_type> ckey_eq_t1;
440
441 ckey_comp_t1 cp1;
442 ckey_eq_t1 eq1;
443
444 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp1,eq1));
445 BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp1,eq1));
446 BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp1,eq1));
447
448 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp1));
449 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1),cp1));
450 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1),cp1));
451
452#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
453 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),0,cp1));
454 BOOST_TEST(is_less (ck1(xyz(0,0,0)),1,cp1));
455 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),-1,cp1));
456#endif
457
458 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp1));
459 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp1));
460 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp1));
461 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp1,eq1));
462 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp1,eq1));
463 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp1,eq1));
464
465 typedef composite_key_result_greater<ckey_t1::result_type> ckey_comp_t2;
466
467 ckey_comp_t2 cp2;
468
469 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp2));
470 BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp2));
471 BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp2));
472
473 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp2));
474 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(1),cp2));
475 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(-1),cp2));
476 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp2));
477 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp2));
478 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp2));
479 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp2));
480 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp2));
481 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp2));
482
483 typedef composite_key_equal_to<
484 modulo_equal,
485 modulo_equal,
486 std::equal_to<int>,
487 std::equal_to<int>
488 > ckey_eq_t2;
489
490 ckey_eq_t2 eq2(
491 boost::make_tuple(
492 t0: modulo_equal(2),
493 t1: modulo_equal(3),
494 t2: std::equal_to<int>(),
495 t3: std::equal_to<int>()));
496 ckey_eq_t2 eq3(eq2);
497 ckey_eq_t2 eq4(
498 get<0>(c&: eq3.key_eqs()),
499 get<1>(c&: eq3.key_eqs()));
500
501 eq3=eq4; /* prevent unused var */
502 eq4=eq3; /* prevent unused var */
503
504 BOOST_TEST( eq2(ck1(xyz(0,0,0)),ck1(xyz(0,0,0))));
505 BOOST_TEST(!eq2(ck1(xyz(0,1,0)),ck1(xyz(0,0,0))));
506 BOOST_TEST(!eq2(ck1(xyz(0,2,0)),ck1(xyz(0,0,0))));
507 BOOST_TEST( eq2(ck1(xyz(0,3,0)),ck1(xyz(0,0,0))));
508 BOOST_TEST(!eq2(ck1(xyz(1,0,0)),ck1(xyz(0,0,0))));
509 BOOST_TEST(!eq2(ck1(xyz(1,1,0)),ck1(xyz(0,0,0))));
510 BOOST_TEST(!eq2(ck1(xyz(1,2,0)),ck1(xyz(0,0,0))));
511 BOOST_TEST(!eq2(ck1(xyz(1,3,0)),ck1(xyz(0,0,0))));
512 BOOST_TEST( eq2(ck1(xyz(2,0,0)),ck1(xyz(0,0,0))));
513 BOOST_TEST(!eq2(ck1(xyz(2,1,0)),ck1(xyz(0,0,0))));
514 BOOST_TEST(!eq2(ck1(xyz(2,2,0)),ck1(xyz(0,0,0))));
515 BOOST_TEST( eq2(ck1(xyz(2,3,0)),ck1(xyz(0,0,0))));
516
517 BOOST_TEST( eq2(TupleMaker::create(0,0,0),ck1(xyz(0,0,0))));
518 BOOST_TEST(!eq2(ck1(xyz(0,1,0)) ,TupleMaker::create(0,0,0)));
519 BOOST_TEST(!eq2(TupleMaker::create(0,2,0),ck1(xyz(0,0,0))));
520 BOOST_TEST( eq2(ck1(xyz(0,3,0)) ,TupleMaker::create(0,0,0)));
521 BOOST_TEST(!eq2(TupleMaker::create(1,0,0),ck1(xyz(0,0,0))));
522 BOOST_TEST(!eq2(ck1(xyz(1,1,0)) ,TupleMaker::create(0,0,0)));
523 BOOST_TEST(!eq2(TupleMaker::create(1,2,0),ck1(xyz(0,0,0))));
524 BOOST_TEST(!eq2(ck1(xyz(1,3,0)) ,TupleMaker::create(0,0,0)));
525 BOOST_TEST( eq2(TupleMaker::create(2,0,0),ck1(xyz(0,0,0))));
526 BOOST_TEST(!eq2(ck1(xyz(2,1,0)) ,TupleMaker::create(0,0,0)));
527 BOOST_TEST(!eq2(TupleMaker::create(2,2,0),ck1(xyz(0,0,0))));
528 BOOST_TEST( eq2(ck1(xyz(2,3,0)) ,TupleMaker::create(0,0,0)));
529
530 typedef composite_key_compare<
531 std::less<int>,
532 std::greater<int>, /* order reversed */
533 std::less<int>
534 > ckey_comp_t3;
535
536 ckey_comp_t3 cp3;
537 ckey_comp_t3 cp4(cp3);
538 ckey_comp_t3 cp5(
539 boost::make_tuple(
540 t0: std::less<int>(),
541 t1: std::greater<int>(),
542 t2: std::less<int>()));
543 ckey_comp_t3 cp6(get<0>(c&: cp3.key_comps()));
544
545 cp4=cp5; /* prevent unused var */
546 cp5=cp6; /* prevent unused var */
547 cp6=cp4; /* prevent unused var */
548
549 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp3));
550 BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp3));
551 BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp3));
552
553 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp3));
554 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1),cp3));
555 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1),cp3));
556 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp3));
557 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp3));
558 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp3));
559 BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp3));
560 BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp3));
561 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp3));
562
563 typedef composite_key<
564 xyz,
565 BOOST_MULTI_INDEX_MEMBER(xyz,int,y), /* members reversed */
566 BOOST_MULTI_INDEX_MEMBER(xyz,int,x)
567 > ckey_t2;
568
569 ckey_t2 ck5;
570
571 BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0))));
572 BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0))));
573 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0))));
574
575 BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp1));
576 BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp1));
577 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp1));
578
579 BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp2));
580 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp2));
581 BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp2));
582
583 BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp3));
584 BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp3));
585 BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp3));
586
587 typedef multi_index_container<
588 xyz,
589 indexed_by<
590 hashed_unique<ckey_t1>
591 >
592 > indexed_t2;
593
594 indexed_t2 mc2;
595 mc2.insert(x: xyz(0,0,0));
596 mc2.insert(x: xyz(0,0,1));
597 mc2.insert(x: xyz(0,1,0));
598 mc2.insert(x: xyz(0,1,1));
599 mc2.insert(x: xyz(1,0,0));
600 mc2.insert(x: xyz(1,0,1));
601 mc2.insert(x: xyz(1,1,0));
602 mc2.insert(x: xyz(1,1,1));
603 mc2.insert(x: xyz(0,0,0));
604 mc2.insert(x: xyz(0,0,1));
605 mc2.insert(x: xyz(0,1,0));
606 mc2.insert(x: xyz(0,1,1));
607 mc2.insert(x: xyz(1,0,0));
608 mc2.insert(x: xyz(1,0,1));
609 mc2.insert(x: xyz(1,1,0));
610 mc2.insert(x: xyz(1,1,1));
611
612 BOOST_TEST(mc2.size()==8);
613 BOOST_TEST(mc2.find(TupleMaker::create(0,0,1))->z==1);
614 BOOST_TEST(ck1(*(mc2.find(TupleMaker::create(1,0,1))))==
615 TupleMaker::create(1,0,1));
616
617 typedef composite_key<
618 xystr,
619 BOOST_MULTI_INDEX_MEMBER(xystr,std::string,str),
620 BOOST_MULTI_INDEX_MEMBER(xystr,int,x),
621 BOOST_MULTI_INDEX_MEMBER(xystr,int,y)
622 > ckey_t3;
623
624 ckey_t3 ck6;
625
626 typedef composite_key_hash<
627 boost::hash<std::string>,
628 boost::hash<int>,
629 boost::hash<int>
630 > ckey_hash_t;
631
632 ckey_hash_t ch1;
633 ckey_hash_t ch2(ch1);
634 ckey_hash_t ch3(
635 boost::make_tuple(
636 t0: boost::hash<std::string>(),
637 t1: boost::hash<int>(),
638 t2: boost::hash<int>()));
639 ckey_hash_t ch4(get<0>(c&: ch1.key_hash_functions()));
640
641 ch2=ch3; /* prevent unused var */
642 ch3=ch4; /* prevent unused var */
643 ch4=ch2; /* prevent unused var */
644
645 BOOST_TEST(
646 ch1(ck6(xystr(0,0,"hello")))==
647 ch1(TupleMaker::create(std::string("hello"),0,0)));
648 BOOST_TEST(
649 ch1(ck6(xystr(4,5,"world")))==
650 ch1(TupleMaker::create(std::string("world"),4,5)));
651
652 typedef boost::hash<composite_key_result<ckey_t3> > ckeyres_hash_t;
653
654 ckeyres_hash_t crh;
655
656 BOOST_TEST(
657 ch1(ck6(xystr(0,0,"hello")))==crh(ck6(xystr(0,0,"hello"))));
658 BOOST_TEST(
659 ch1(ck6(xystr(4,5,"world")))==crh(ck6(xystr(4,5,"world"))));
660}
661
662void test_composite_key()
663{
664 test_composite_key_template<boost_tuple_maker>();
665
666#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
667 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
668 test_composite_key_template<std_tuple_maker>();
669#endif
670}
671

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