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 | |
25 | using namespace boost::multi_index; |
26 | using namespace boost::tuples; |
27 | |
28 | struct 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 | |
39 | template<typename T> |
40 | struct 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 | |
50 | template<typename CompositeKeyResult> |
51 | struct 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) |
62 | struct 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 | |
73 | template<typename T> |
74 | struct 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 | |
84 | template<typename T> |
85 | struct 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 |
100 | template<typename T> |
101 | struct 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 | |
113 | template<typename CompositeKeyResult,typename T2> |
114 | struct 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 | |
186 | template<typename CompositeKeyResult,typename T2> |
187 | struct 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 | |
241 | template<typename CompositeKeyResult,typename T2> |
242 | struct 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 | |
252 | template<typename CompositeKeyResult,typename T2> |
253 | static bool is_less(const CompositeKeyResult& x,const T2& y) |
254 | { |
255 | return comparison_helper<CompositeKeyResult,T2>::is_less(x,y); |
256 | } |
257 | |
258 | template<typename CompositeKeyResult,typename T2> |
259 | static bool is_greater(const CompositeKeyResult& x,const T2& y) |
260 | { |
261 | return comparison_helper<CompositeKeyResult,T2>::is_greater(x,y); |
262 | } |
263 | |
264 | template<typename CompositeKeyResult,typename T2> |
265 | static bool is_equiv(const CompositeKeyResult& x,const T2& y) |
266 | { |
267 | return comparison_helper<CompositeKeyResult,T2>::is_equiv(x,y); |
268 | } |
269 | |
270 | template<typename T1,typename T2,typename Compare> |
271 | static bool is_less(const T1& x,const T2& y,const Compare& c) |
272 | { |
273 | return c(x,y)&&!c(y,x); |
274 | } |
275 | |
276 | template<typename T1,typename T2,typename Compare> |
277 | static bool is_greater(const T1& x,const T2& y,const Compare& c) |
278 | { |
279 | return c(y,x)&&!c(x,y); |
280 | } |
281 | |
282 | template<typename T1,typename T2,typename Compare> |
283 | static bool is_equiv(const T1& x,const T2& y,const Compare& c) |
284 | { |
285 | return !c(x,y)&&!c(y,x); |
286 | } |
287 | |
288 | template<typename T1,typename T2,typename Compare,typename Equiv> |
289 | static 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 | |
295 | template<typename T1,typename T2,typename Compare,typename Equiv> |
296 | static 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 | |
302 | template<typename T1,typename T2,typename Compare,typename Equiv> |
303 | static 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 | |
309 | struct 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 | |
318 | struct modulo_equal |
319 | { |
320 | modulo_equal(int i):i_(i){} |
321 | bool operator ()(int x,int y)const{return (x%i_)==(y%i_);} |
322 | |
323 | private: |
324 | int i_; |
325 | }; |
326 | |
327 | struct 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) \ |
337 | template<BOOST_PP_ENUM_PARAMS(n,typename T)> \ |
338 | static tuple<BOOST_PP_ENUM_PARAMS(n,T)> \ |
339 | create(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) \ |
345 | struct name \ |
346 | { \ |
347 | static tuple<> create(){return tuple<>();} \ |
348 | BOOST_PP_REPEAT_FROM_TO(1,5,TUPLE_MAKER_CREATE,tuple) \ |
349 | }; |
350 | |
351 | DEFINE_TUPLE_MAKER(boost_tuple_maker,boost::tuple) |
352 | |
353 | #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ |
354 | !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) |
355 | DEFINE_TUPLE_MAKER(std_tuple_maker,std::tuple) |
356 | #endif |
357 | |
358 | #undef DEFINE_TUPLE_MAKER |
359 | #undef TUPLE_MAKER_CREATE |
360 | |
361 | template<typename TupleMaker> |
362 | void 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 | |
662 | void 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 | |