]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multi_index/include/boost/multi_index/composite_key.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / multi_index / include / boost / multi_index / composite_key.hpp
1 /* Copyright 2003-2015 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/multi_index for library home page.
7 */
8
9 #ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
10 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <boost/functional/hash_fwd.hpp>
18 #include <boost/multi_index/detail/access_specifier.hpp>
19 #include <boost/mpl/eval_if.hpp>
20 #include <boost/mpl/identity.hpp>
21 #include <boost/mpl/if.hpp>
22 #include <boost/mpl/or.hpp>
23 #include <boost/preprocessor/cat.hpp>
24 #include <boost/preprocessor/control/expr_if.hpp>
25 #include <boost/preprocessor/list/at.hpp>
26 #include <boost/preprocessor/repetition/enum.hpp>
27 #include <boost/preprocessor/repetition/enum_params.hpp>
28 #include <boost/static_assert.hpp>
29 #include <boost/tuple/tuple.hpp>
30 #include <boost/type_traits/is_same.hpp>
31 #include <boost/utility/enable_if.hpp>
32 #include <functional>
33
34 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
35 #include <boost/ref.hpp>
36 #endif
37
38 #if !defined(BOOST_NO_SFINAE)
39 #include <boost/type_traits/is_convertible.hpp>
40 #endif
41
42 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
43 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
44 #include <boost/multi_index/detail/cons_stdtuple.hpp>
45 #endif
46
47 /* A composite key stores n key extractors and "computes" the
48 * result on a given value as a packed reference to the value and
49 * the composite key itself. Actual invocations to the component
50 * key extractors are lazily performed when executing an operation
51 * on composite_key results (equality, comparison, hashing.)
52 * As the other key extractors in Boost.MultiIndex, composite_key<T,...>
53 * is overloaded to work on chained pointers to T and reference_wrappers
54 * of T.
55 */
56
57 /* This user_definable macro limits the number of elements of a composite
58 * key; useful for shortening resulting symbol names (MSVC++ 6.0, for
59 * instance has problems coping with very long symbol names.)
60 * NB: This cannot exceed the maximum number of arguments of
61 * boost::tuple. In Boost 1.32, the limit is 10.
62 */
63
64 #if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE)
65 #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10
66 #endif
67
68 /* maximum number of key extractors in a composite key */
69
70 #if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */
71 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \
72 BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE
73 #else
74 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10
75 #endif
76
77 /* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
78
79 #define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \
80 BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data)
81
82 /* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
83
84 #define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \
85 BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param)
86
87 /* if n==0 -> text0
88 * otherwise -> textn=tuples::null_type
89 */
90
91 #define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \
92 typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type)
93
94 /* const textn& kn=textn() */
95
96 #define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \
97 const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)()
98
99 /* typename list(0)<list(1),n>::type */
100
101 #define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \
102 BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \
103 BOOST_PP_LIST_AT(list,1),n \
104 >::type
105
106 namespace boost{
107
108 template<class T> class reference_wrapper; /* fwd decl. */
109
110 namespace multi_index{
111
112 namespace detail{
113
114 /* n-th key extractor of a composite key */
115
116 template<typename CompositeKey,int N>
117 struct nth_key_from_value
118 {
119 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
120 typedef typename mpl::eval_if_c<
121 N<tuples::length<key_extractor_tuple>::value,
122 tuples::element<N,key_extractor_tuple>,
123 mpl::identity<tuples::null_type>
124 >::type type;
125 };
126
127 /* nth_composite_key_##name<CompositeKey,N>::type yields
128 * functor<nth_key_from_value<CompositeKey,N> >, or tuples::null_type
129 * if N exceeds the length of the composite key.
130 */
131
132 #define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \
133 template<typename KeyFromValue> \
134 struct BOOST_PP_CAT(key_,name) \
135 { \
136 typedef functor<typename KeyFromValue::result_type> type; \
137 }; \
138 \
139 template<> \
140 struct BOOST_PP_CAT(key_,name)<tuples::null_type> \
141 { \
142 typedef tuples::null_type type; \
143 }; \
144 \
145 template<typename CompositeKey,int N> \
146 struct BOOST_PP_CAT(nth_composite_key_,name) \
147 { \
148 typedef typename nth_key_from_value<CompositeKey,N>::type key_from_value; \
149 typedef typename BOOST_PP_CAT(key_,name)<key_from_value>::type type; \
150 };
151
152 /* nth_composite_key_equal_to
153 * nth_composite_key_less
154 * nth_composite_key_greater
155 * nth_composite_key_hash
156 */
157
158 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to)
159 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less)
160 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater)
161 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash)
162
163 /* used for defining equality and comparison ops of composite_key_result */
164
165 #define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text
166
167 struct generic_operator_equal
168 {
169 template<typename T,typename Q>
170 bool operator()(const T& x,const Q& y)const{return x==y;}
171 };
172
173 typedef tuple<
174 BOOST_MULTI_INDEX_CK_ENUM(
175 BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
176 detail::generic_operator_equal)> generic_operator_equal_tuple;
177
178 struct generic_operator_less
179 {
180 template<typename T,typename Q>
181 bool operator()(const T& x,const Q& y)const{return x<y;}
182 };
183
184 typedef tuple<
185 BOOST_MULTI_INDEX_CK_ENUM(
186 BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
187 detail::generic_operator_less)> generic_operator_less_tuple;
188
189 /* Metaprogramming machinery for implementing equality, comparison and
190 * hashing operations of composite_key_result.
191 *
192 * equal_* checks for equality between composite_key_results and
193 * between those and tuples, accepting a tuple of basic equality functors.
194 * compare_* does lexicographical comparison.
195 * hash_* computes a combination of elementwise hash values.
196 */
197
198 template
199 <
200 typename KeyCons1,typename Value1,
201 typename KeyCons2, typename Value2,
202 typename EqualCons
203 >
204 struct equal_ckey_ckey; /* fwd decl. */
205
206 template
207 <
208 typename KeyCons1,typename Value1,
209 typename KeyCons2, typename Value2,
210 typename EqualCons
211 >
212 struct equal_ckey_ckey_terminal
213 {
214 static bool compare(
215 const KeyCons1&,const Value1&,
216 const KeyCons2&,const Value2&,
217 const EqualCons&)
218 {
219 return true;
220 }
221 };
222
223 template
224 <
225 typename KeyCons1,typename Value1,
226 typename KeyCons2, typename Value2,
227 typename EqualCons
228 >
229 struct equal_ckey_ckey_normal
230 {
231 static bool compare(
232 const KeyCons1& c0,const Value1& v0,
233 const KeyCons2& c1,const Value2& v1,
234 const EqualCons& eq)
235 {
236 if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false;
237 return equal_ckey_ckey<
238 BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
239 BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
240 BOOST_DEDUCED_TYPENAME EqualCons::tail_type
241 >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail());
242 }
243 };
244
245 template
246 <
247 typename KeyCons1,typename Value1,
248 typename KeyCons2, typename Value2,
249 typename EqualCons
250 >
251 struct equal_ckey_ckey:
252 mpl::if_<
253 mpl::or_<
254 is_same<KeyCons1,tuples::null_type>,
255 is_same<KeyCons2,tuples::null_type>
256 >,
257 equal_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>,
258 equal_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>
259 >::type
260 {
261 };
262
263 template
264 <
265 typename KeyCons,typename Value,
266 typename ValCons,typename EqualCons
267 >
268 struct equal_ckey_cval; /* fwd decl. */
269
270 template
271 <
272 typename KeyCons,typename Value,
273 typename ValCons,typename EqualCons
274 >
275 struct equal_ckey_cval_terminal
276 {
277 static bool compare(
278 const KeyCons&,const Value&,const ValCons&,const EqualCons&)
279 {
280 return true;
281 }
282
283 static bool compare(
284 const ValCons&,const KeyCons&,const Value&,const EqualCons&)
285 {
286 return true;
287 }
288 };
289
290 template
291 <
292 typename KeyCons,typename Value,
293 typename ValCons,typename EqualCons
294 >
295 struct equal_ckey_cval_normal
296 {
297 static bool compare(
298 const KeyCons& c,const Value& v,const ValCons& vc,
299 const EqualCons& eq)
300 {
301 if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false;
302 return equal_ckey_cval<
303 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
304 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
305 BOOST_DEDUCED_TYPENAME EqualCons::tail_type
306 >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail());
307 }
308
309 static bool compare(
310 const ValCons& vc,const KeyCons& c,const Value& v,
311 const EqualCons& eq)
312 {
313 if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false;
314 return equal_ckey_cval<
315 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
316 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
317 BOOST_DEDUCED_TYPENAME EqualCons::tail_type
318 >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail());
319 }
320 };
321
322 template
323 <
324 typename KeyCons,typename Value,
325 typename ValCons,typename EqualCons
326 >
327 struct equal_ckey_cval:
328 mpl::if_<
329 mpl::or_<
330 is_same<KeyCons,tuples::null_type>,
331 is_same<ValCons,tuples::null_type>
332 >,
333 equal_ckey_cval_terminal<KeyCons,Value,ValCons,EqualCons>,
334 equal_ckey_cval_normal<KeyCons,Value,ValCons,EqualCons>
335 >::type
336 {
337 };
338
339 template
340 <
341 typename KeyCons1,typename Value1,
342 typename KeyCons2, typename Value2,
343 typename CompareCons
344 >
345 struct compare_ckey_ckey; /* fwd decl. */
346
347 template
348 <
349 typename KeyCons1,typename Value1,
350 typename KeyCons2, typename Value2,
351 typename CompareCons
352 >
353 struct compare_ckey_ckey_terminal
354 {
355 static bool compare(
356 const KeyCons1&,const Value1&,
357 const KeyCons2&,const Value2&,
358 const CompareCons&)
359 {
360 return false;
361 }
362 };
363
364 template
365 <
366 typename KeyCons1,typename Value1,
367 typename KeyCons2, typename Value2,
368 typename CompareCons
369 >
370 struct compare_ckey_ckey_normal
371 {
372 static bool compare(
373 const KeyCons1& c0,const Value1& v0,
374 const KeyCons2& c1,const Value2& v1,
375 const CompareCons& comp)
376 {
377 if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true;
378 if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false;
379 return compare_ckey_ckey<
380 BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
381 BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
382 BOOST_DEDUCED_TYPENAME CompareCons::tail_type
383 >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail());
384 }
385 };
386
387 template
388 <
389 typename KeyCons1,typename Value1,
390 typename KeyCons2, typename Value2,
391 typename CompareCons
392 >
393 struct compare_ckey_ckey:
394 mpl::if_<
395 mpl::or_<
396 is_same<KeyCons1,tuples::null_type>,
397 is_same<KeyCons2,tuples::null_type>
398 >,
399 compare_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>,
400 compare_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>
401 >::type
402 {
403 };
404
405 template
406 <
407 typename KeyCons,typename Value,
408 typename ValCons,typename CompareCons
409 >
410 struct compare_ckey_cval; /* fwd decl. */
411
412 template
413 <
414 typename KeyCons,typename Value,
415 typename ValCons,typename CompareCons
416 >
417 struct compare_ckey_cval_terminal
418 {
419 static bool compare(
420 const KeyCons&,const Value&,const ValCons&,const CompareCons&)
421 {
422 return false;
423 }
424
425 static bool compare(
426 const ValCons&,const KeyCons&,const Value&,const CompareCons&)
427 {
428 return false;
429 }
430 };
431
432 template
433 <
434 typename KeyCons,typename Value,
435 typename ValCons,typename CompareCons
436 >
437 struct compare_ckey_cval_normal
438 {
439 static bool compare(
440 const KeyCons& c,const Value& v,const ValCons& vc,
441 const CompareCons& comp)
442 {
443 if(comp.get_head()(c.get_head()(v),vc.get_head()))return true;
444 if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false;
445 return compare_ckey_cval<
446 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
447 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
448 BOOST_DEDUCED_TYPENAME CompareCons::tail_type
449 >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail());
450 }
451
452 static bool compare(
453 const ValCons& vc,const KeyCons& c,const Value& v,
454 const CompareCons& comp)
455 {
456 if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true;
457 if(comp.get_head()(c.get_head()(v),vc.get_head()))return false;
458 return compare_ckey_cval<
459 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
460 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
461 BOOST_DEDUCED_TYPENAME CompareCons::tail_type
462 >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail());
463 }
464 };
465
466 template
467 <
468 typename KeyCons,typename Value,
469 typename ValCons,typename CompareCons
470 >
471 struct compare_ckey_cval:
472 mpl::if_<
473 mpl::or_<
474 is_same<KeyCons,tuples::null_type>,
475 is_same<ValCons,tuples::null_type>
476 >,
477 compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>,
478 compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons>
479 >::type
480 {
481 };
482
483 template<typename KeyCons,typename Value,typename HashCons>
484 struct hash_ckey; /* fwd decl. */
485
486 template<typename KeyCons,typename Value,typename HashCons>
487 struct hash_ckey_terminal
488 {
489 static std::size_t hash(
490 const KeyCons&,const Value&,const HashCons&,std::size_t carry)
491 {
492 return carry;
493 }
494 };
495
496 template<typename KeyCons,typename Value,typename HashCons>
497 struct hash_ckey_normal
498 {
499 static std::size_t hash(
500 const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0)
501 {
502 /* same hashing formula as boost::hash_combine */
503
504 carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2);
505 return hash_ckey<
506 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
507 BOOST_DEDUCED_TYPENAME HashCons::tail_type
508 >::hash(c.get_tail(),v,h.get_tail(),carry);
509 }
510 };
511
512 template<typename KeyCons,typename Value,typename HashCons>
513 struct hash_ckey:
514 mpl::if_<
515 is_same<KeyCons,tuples::null_type>,
516 hash_ckey_terminal<KeyCons,Value,HashCons>,
517 hash_ckey_normal<KeyCons,Value,HashCons>
518 >::type
519 {
520 };
521
522 template<typename ValCons,typename HashCons>
523 struct hash_cval; /* fwd decl. */
524
525 template<typename ValCons,typename HashCons>
526 struct hash_cval_terminal
527 {
528 static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry)
529 {
530 return carry;
531 }
532 };
533
534 template<typename ValCons,typename HashCons>
535 struct hash_cval_normal
536 {
537 static std::size_t hash(
538 const ValCons& vc,const HashCons& h,std::size_t carry=0)
539 {
540 carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2);
541 return hash_cval<
542 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
543 BOOST_DEDUCED_TYPENAME HashCons::tail_type
544 >::hash(vc.get_tail(),h.get_tail(),carry);
545 }
546 };
547
548 template<typename ValCons,typename HashCons>
549 struct hash_cval:
550 mpl::if_<
551 is_same<ValCons,tuples::null_type>,
552 hash_cval_terminal<ValCons,HashCons>,
553 hash_cval_normal<ValCons,HashCons>
554 >::type
555 {
556 };
557
558 } /* namespace multi_index::detail */
559
560 /* composite_key_result */
561
562 #if defined(BOOST_MSVC)
563 #pragma warning(push)
564 #pragma warning(disable:4512)
565 #endif
566
567 template<typename CompositeKey>
568 struct composite_key_result
569 {
570 typedef CompositeKey composite_key_type;
571 typedef typename composite_key_type::value_type value_type;
572
573 composite_key_result(
574 const composite_key_type& composite_key_,const value_type& value_):
575 composite_key(composite_key_),value(value_)
576 {}
577
578 const composite_key_type& composite_key;
579 const value_type& value;
580 };
581
582 #if defined(BOOST_MSVC)
583 #pragma warning(pop)
584 #endif
585
586 /* composite_key */
587
588 template<
589 typename Value,
590 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
591 >
592 struct composite_key:
593 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)>
594 {
595 private:
596 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super;
597
598 public:
599 typedef super key_extractor_tuple;
600 typedef Value value_type;
601 typedef composite_key_result<composite_key> result_type;
602
603 composite_key(
604 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)):
605 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
606 {}
607
608 composite_key(const key_extractor_tuple& x):super(x){}
609
610 const key_extractor_tuple& key_extractors()const{return *this;}
611 key_extractor_tuple& key_extractors(){return *this;}
612
613 template<typename ChainedPtr>
614
615 #if !defined(BOOST_NO_SFINAE)
616 typename disable_if<
617 is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
618 #else
619 result_type
620 #endif
621
622 operator()(const ChainedPtr& x)const
623 {
624 return operator()(*x);
625 }
626
627 result_type operator()(const value_type& x)const
628 {
629 return result_type(*this,x);
630 }
631
632 result_type operator()(const reference_wrapper<const value_type>& x)const
633 {
634 return result_type(*this,x.get());
635 }
636
637 result_type operator()(const reference_wrapper<value_type>& x)const
638 {
639 return result_type(*this,x.get());
640 }
641 };
642
643 /* comparison operators */
644
645 /* == */
646
647 template<typename CompositeKey1,typename CompositeKey2>
648 inline bool operator==(
649 const composite_key_result<CompositeKey1>& x,
650 const composite_key_result<CompositeKey2>& y)
651 {
652 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
653 typedef typename CompositeKey1::value_type value_type1;
654 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
655 typedef typename CompositeKey2::value_type value_type2;
656
657 BOOST_STATIC_ASSERT(
658 tuples::length<key_extractor_tuple1>::value==
659 tuples::length<key_extractor_tuple2>::value);
660
661 return detail::equal_ckey_ckey<
662 key_extractor_tuple1,value_type1,
663 key_extractor_tuple2,value_type2,
664 detail::generic_operator_equal_tuple
665 >::compare(
666 x.composite_key.key_extractors(),x.value,
667 y.composite_key.key_extractors(),y.value,
668 detail::generic_operator_equal_tuple());
669 }
670
671 template<
672 typename CompositeKey,
673 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
674 >
675 inline bool operator==(
676 const composite_key_result<CompositeKey>& x,
677 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
678 {
679 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
680 typedef typename CompositeKey::value_type value_type;
681 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
682
683 BOOST_STATIC_ASSERT(
684 tuples::length<key_extractor_tuple>::value==
685 tuples::length<key_tuple>::value);
686
687 return detail::equal_ckey_cval<
688 key_extractor_tuple,value_type,
689 key_tuple,detail::generic_operator_equal_tuple
690 >::compare(
691 x.composite_key.key_extractors(),x.value,
692 y,detail::generic_operator_equal_tuple());
693 }
694
695 template
696 <
697 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
698 typename CompositeKey
699 >
700 inline bool operator==(
701 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
702 const composite_key_result<CompositeKey>& y)
703 {
704 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
705 typedef typename CompositeKey::value_type value_type;
706 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
707
708 BOOST_STATIC_ASSERT(
709 tuples::length<key_extractor_tuple>::value==
710 tuples::length<key_tuple>::value);
711
712 return detail::equal_ckey_cval<
713 key_extractor_tuple,value_type,
714 key_tuple,detail::generic_operator_equal_tuple
715 >::compare(
716 x,y.composite_key.key_extractors(),
717 y.value,detail::generic_operator_equal_tuple());
718 }
719
720 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
721 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
722 template<typename CompositeKey,typename... Values>
723 inline bool operator==(
724 const composite_key_result<CompositeKey>& x,
725 const std::tuple<Values...>& y)
726 {
727 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
728 typedef typename CompositeKey::value_type value_type;
729 typedef std::tuple<Values...> key_tuple;
730 typedef typename detail::cons_stdtuple_ctor<
731 key_tuple>::result_type cons_key_tuple;
732
733 BOOST_STATIC_ASSERT(
734 static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
735 std::tuple_size<key_tuple>::value);
736
737 return detail::equal_ckey_cval<
738 key_extractor_tuple,value_type,
739 cons_key_tuple,detail::generic_operator_equal_tuple
740 >::compare(
741 x.composite_key.key_extractors(),x.value,
742 detail::make_cons_stdtuple(y),detail::generic_operator_equal_tuple());
743 }
744
745 template<typename CompositeKey,typename... Values>
746 inline bool operator==(
747 const std::tuple<Values...>& x,
748 const composite_key_result<CompositeKey>& y)
749 {
750 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
751 typedef typename CompositeKey::value_type value_type;
752 typedef std::tuple<Values...> key_tuple;
753 typedef typename detail::cons_stdtuple_ctor<
754 key_tuple>::result_type cons_key_tuple;
755
756 BOOST_STATIC_ASSERT(
757 static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
758 std::tuple_size<key_tuple>::value);
759
760 return detail::equal_ckey_cval<
761 key_extractor_tuple,value_type,
762 cons_key_tuple,detail::generic_operator_equal_tuple
763 >::compare(
764 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
765 y.value,detail::generic_operator_equal_tuple());
766 }
767 #endif
768
769 /* < */
770
771 template<typename CompositeKey1,typename CompositeKey2>
772 inline bool operator<(
773 const composite_key_result<CompositeKey1>& x,
774 const composite_key_result<CompositeKey2>& y)
775 {
776 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
777 typedef typename CompositeKey1::value_type value_type1;
778 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
779 typedef typename CompositeKey2::value_type value_type2;
780
781 return detail::compare_ckey_ckey<
782 key_extractor_tuple1,value_type1,
783 key_extractor_tuple2,value_type2,
784 detail::generic_operator_less_tuple
785 >::compare(
786 x.composite_key.key_extractors(),x.value,
787 y.composite_key.key_extractors(),y.value,
788 detail::generic_operator_less_tuple());
789 }
790
791 template
792 <
793 typename CompositeKey,
794 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
795 >
796 inline bool operator<(
797 const composite_key_result<CompositeKey>& x,
798 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
799 {
800 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
801 typedef typename CompositeKey::value_type value_type;
802 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
803
804 return detail::compare_ckey_cval<
805 key_extractor_tuple,value_type,
806 key_tuple,detail::generic_operator_less_tuple
807 >::compare(
808 x.composite_key.key_extractors(),x.value,
809 y,detail::generic_operator_less_tuple());
810 }
811
812 template
813 <
814 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
815 typename CompositeKey
816 >
817 inline bool operator<(
818 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
819 const composite_key_result<CompositeKey>& y)
820 {
821 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
822 typedef typename CompositeKey::value_type value_type;
823 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
824
825 return detail::compare_ckey_cval<
826 key_extractor_tuple,value_type,
827 key_tuple,detail::generic_operator_less_tuple
828 >::compare(
829 x,y.composite_key.key_extractors(),
830 y.value,detail::generic_operator_less_tuple());
831 }
832
833 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
834 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
835 template<typename CompositeKey,typename... Values>
836 inline bool operator<(
837 const composite_key_result<CompositeKey>& x,
838 const std::tuple<Values...>& y)
839 {
840 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
841 typedef typename CompositeKey::value_type value_type;
842 typedef std::tuple<Values...> key_tuple;
843 typedef typename detail::cons_stdtuple_ctor<
844 key_tuple>::result_type cons_key_tuple;
845
846 return detail::compare_ckey_cval<
847 key_extractor_tuple,value_type,
848 cons_key_tuple,detail::generic_operator_less_tuple
849 >::compare(
850 x.composite_key.key_extractors(),x.value,
851 detail::make_cons_stdtuple(y),detail::generic_operator_less_tuple());
852 }
853
854 template<typename CompositeKey,typename... Values>
855 inline bool operator<(
856 const std::tuple<Values...>& x,
857 const composite_key_result<CompositeKey>& y)
858 {
859 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
860 typedef typename CompositeKey::value_type value_type;
861 typedef std::tuple<Values...> key_tuple;
862 typedef typename detail::cons_stdtuple_ctor<
863 key_tuple>::result_type cons_key_tuple;
864
865 return detail::compare_ckey_cval<
866 key_extractor_tuple,value_type,
867 cons_key_tuple,detail::generic_operator_less_tuple
868 >::compare(
869 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
870 y.value,detail::generic_operator_less_tuple());
871 }
872 #endif
873
874 /* rest of comparison operators */
875
876 #define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \
877 template<t1,t2> inline bool operator!=(const a1& x,const a2& y) \
878 { \
879 return !(x==y); \
880 } \
881 \
882 template<t1,t2> inline bool operator>(const a1& x,const a2& y) \
883 { \
884 return y<x; \
885 } \
886 \
887 template<t1,t2> inline bool operator>=(const a1& x,const a2& y) \
888 { \
889 return !(x<y); \
890 } \
891 \
892 template<t1,t2> inline bool operator<=(const a1& x,const a2& y) \
893 { \
894 return !(y<x); \
895 }
896
897 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
898 typename CompositeKey1,
899 typename CompositeKey2,
900 composite_key_result<CompositeKey1>,
901 composite_key_result<CompositeKey2>
902 )
903
904 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
905 typename CompositeKey,
906 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
907 composite_key_result<CompositeKey>,
908 tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>
909 )
910
911 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
912 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
913 typename CompositeKey,
914 tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>,
915 composite_key_result<CompositeKey>
916 )
917
918 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
919 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
920 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
921 typename CompositeKey,
922 typename... Values,
923 composite_key_result<CompositeKey>,
924 std::tuple<Values...>
925 )
926
927 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
928 typename CompositeKey,
929 typename... Values,
930 std::tuple<Values...>,
931 composite_key_result<CompositeKey>
932 )
933 #endif
934
935 /* composite_key_equal_to */
936
937 template
938 <
939 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred)
940 >
941 struct composite_key_equal_to:
942 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)>
943 {
944 private:
945 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super;
946
947 public:
948 typedef super key_eq_tuple;
949
950 composite_key_equal_to(
951 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)):
952 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
953 {}
954
955 composite_key_equal_to(const key_eq_tuple& x):super(x){}
956
957 const key_eq_tuple& key_eqs()const{return *this;}
958 key_eq_tuple& key_eqs(){return *this;}
959
960 template<typename CompositeKey1,typename CompositeKey2>
961 bool operator()(
962 const composite_key_result<CompositeKey1> & x,
963 const composite_key_result<CompositeKey2> & y)const
964 {
965 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
966 typedef typename CompositeKey1::value_type value_type1;
967 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
968 typedef typename CompositeKey2::value_type value_type2;
969
970 BOOST_STATIC_ASSERT(
971 tuples::length<key_extractor_tuple1>::value<=
972 tuples::length<key_eq_tuple>::value&&
973 tuples::length<key_extractor_tuple1>::value==
974 tuples::length<key_extractor_tuple2>::value);
975
976 return detail::equal_ckey_ckey<
977 key_extractor_tuple1,value_type1,
978 key_extractor_tuple2,value_type2,
979 key_eq_tuple
980 >::compare(
981 x.composite_key.key_extractors(),x.value,
982 y.composite_key.key_extractors(),y.value,
983 key_eqs());
984 }
985
986 template
987 <
988 typename CompositeKey,
989 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
990 >
991 bool operator()(
992 const composite_key_result<CompositeKey>& x,
993 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
994 {
995 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
996 typedef typename CompositeKey::value_type value_type;
997 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
998
999 BOOST_STATIC_ASSERT(
1000 tuples::length<key_extractor_tuple>::value<=
1001 tuples::length<key_eq_tuple>::value&&
1002 tuples::length<key_extractor_tuple>::value==
1003 tuples::length<key_tuple>::value);
1004
1005 return detail::equal_ckey_cval<
1006 key_extractor_tuple,value_type,
1007 key_tuple,key_eq_tuple
1008 >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs());
1009 }
1010
1011 template
1012 <
1013 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1014 typename CompositeKey
1015 >
1016 bool operator()(
1017 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1018 const composite_key_result<CompositeKey>& y)const
1019 {
1020 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1021 typedef typename CompositeKey::value_type value_type;
1022 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1023
1024 BOOST_STATIC_ASSERT(
1025 tuples::length<key_tuple>::value<=
1026 tuples::length<key_eq_tuple>::value&&
1027 tuples::length<key_tuple>::value==
1028 tuples::length<key_extractor_tuple>::value);
1029
1030 return detail::equal_ckey_cval<
1031 key_extractor_tuple,value_type,
1032 key_tuple,key_eq_tuple
1033 >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs());
1034 }
1035
1036 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
1037 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1038 template<typename CompositeKey,typename... Values>
1039 bool operator()(
1040 const composite_key_result<CompositeKey>& x,
1041 const std::tuple<Values...>& y)const
1042 {
1043 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1044 typedef typename CompositeKey::value_type value_type;
1045 typedef std::tuple<Values...> key_tuple;
1046 typedef typename detail::cons_stdtuple_ctor<
1047 key_tuple>::result_type cons_key_tuple;
1048
1049 BOOST_STATIC_ASSERT(
1050 tuples::length<key_extractor_tuple>::value<=
1051 tuples::length<key_eq_tuple>::value&&
1052 static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
1053 std::tuple_size<key_tuple>::value);
1054
1055 return detail::equal_ckey_cval<
1056 key_extractor_tuple,value_type,
1057 cons_key_tuple,key_eq_tuple
1058 >::compare(
1059 x.composite_key.key_extractors(),x.value,
1060 detail::make_cons_stdtuple(y),key_eqs());
1061 }
1062
1063 template<typename CompositeKey,typename... Values>
1064 bool operator()(
1065 const std::tuple<Values...>& x,
1066 const composite_key_result<CompositeKey>& y)const
1067 {
1068 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1069 typedef typename CompositeKey::value_type value_type;
1070 typedef std::tuple<Values...> key_tuple;
1071 typedef typename detail::cons_stdtuple_ctor<
1072 key_tuple>::result_type cons_key_tuple;
1073
1074 BOOST_STATIC_ASSERT(
1075 std::tuple_size<key_tuple>::value<=
1076 static_cast<std::size_t>(tuples::length<key_eq_tuple>::value)&&
1077 std::tuple_size<key_tuple>::value==
1078 static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value));
1079
1080 return detail::equal_ckey_cval<
1081 key_extractor_tuple,value_type,
1082 cons_key_tuple,key_eq_tuple
1083 >::compare(
1084 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
1085 y.value,key_eqs());
1086 }
1087 #endif
1088 };
1089
1090 /* composite_key_compare */
1091
1092 template
1093 <
1094 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare)
1095 >
1096 struct composite_key_compare:
1097 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)>
1098 {
1099 private:
1100 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> super;
1101
1102 public:
1103 typedef super key_comp_tuple;
1104
1105 composite_key_compare(
1106 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)):
1107 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
1108 {}
1109
1110 composite_key_compare(const key_comp_tuple& x):super(x){}
1111
1112 const key_comp_tuple& key_comps()const{return *this;}
1113 key_comp_tuple& key_comps(){return *this;}
1114
1115 template<typename CompositeKey1,typename CompositeKey2>
1116 bool operator()(
1117 const composite_key_result<CompositeKey1> & x,
1118 const composite_key_result<CompositeKey2> & y)const
1119 {
1120 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
1121 typedef typename CompositeKey1::value_type value_type1;
1122 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
1123 typedef typename CompositeKey2::value_type value_type2;
1124
1125 BOOST_STATIC_ASSERT(
1126 tuples::length<key_extractor_tuple1>::value<=
1127 tuples::length<key_comp_tuple>::value||
1128 tuples::length<key_extractor_tuple2>::value<=
1129 tuples::length<key_comp_tuple>::value);
1130
1131 return detail::compare_ckey_ckey<
1132 key_extractor_tuple1,value_type1,
1133 key_extractor_tuple2,value_type2,
1134 key_comp_tuple
1135 >::compare(
1136 x.composite_key.key_extractors(),x.value,
1137 y.composite_key.key_extractors(),y.value,
1138 key_comps());
1139 }
1140
1141 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
1142 template<typename CompositeKey,typename Value>
1143 bool operator()(
1144 const composite_key_result<CompositeKey>& x,
1145 const Value& y)const
1146 {
1147 return operator()(x,boost::make_tuple(boost::cref(y)));
1148 }
1149 #endif
1150
1151 template
1152 <
1153 typename CompositeKey,
1154 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
1155 >
1156 bool operator()(
1157 const composite_key_result<CompositeKey>& x,
1158 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
1159 {
1160 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1161 typedef typename CompositeKey::value_type value_type;
1162 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1163
1164 BOOST_STATIC_ASSERT(
1165 tuples::length<key_extractor_tuple>::value<=
1166 tuples::length<key_comp_tuple>::value||
1167 tuples::length<key_tuple>::value<=
1168 tuples::length<key_comp_tuple>::value);
1169
1170 return detail::compare_ckey_cval<
1171 key_extractor_tuple,value_type,
1172 key_tuple,key_comp_tuple
1173 >::compare(x.composite_key.key_extractors(),x.value,y,key_comps());
1174 }
1175
1176 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
1177 template<typename Value,typename CompositeKey>
1178 bool operator()(
1179 const Value& x,
1180 const composite_key_result<CompositeKey>& y)const
1181 {
1182 return operator()(boost::make_tuple(boost::cref(x)),y);
1183 }
1184 #endif
1185
1186 template
1187 <
1188 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1189 typename CompositeKey
1190 >
1191 bool operator()(
1192 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1193 const composite_key_result<CompositeKey>& y)const
1194 {
1195 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1196 typedef typename CompositeKey::value_type value_type;
1197 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1198
1199 BOOST_STATIC_ASSERT(
1200 tuples::length<key_tuple>::value<=
1201 tuples::length<key_comp_tuple>::value||
1202 tuples::length<key_extractor_tuple>::value<=
1203 tuples::length<key_comp_tuple>::value);
1204
1205 return detail::compare_ckey_cval<
1206 key_extractor_tuple,value_type,
1207 key_tuple,key_comp_tuple
1208 >::compare(x,y.composite_key.key_extractors(),y.value,key_comps());
1209 }
1210
1211 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
1212 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1213 template<typename CompositeKey,typename... Values>
1214 bool operator()(
1215 const composite_key_result<CompositeKey>& x,
1216 const std::tuple<Values...>& y)const
1217 {
1218 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1219 typedef typename CompositeKey::value_type value_type;
1220 typedef std::tuple<Values...> key_tuple;
1221 typedef typename detail::cons_stdtuple_ctor<
1222 key_tuple>::result_type cons_key_tuple;
1223
1224 BOOST_STATIC_ASSERT(
1225 tuples::length<key_extractor_tuple>::value<=
1226 tuples::length<key_comp_tuple>::value||
1227 std::tuple_size<key_tuple>::value<=
1228 static_cast<std::size_t>(tuples::length<key_comp_tuple>::value));
1229
1230 return detail::compare_ckey_cval<
1231 key_extractor_tuple,value_type,
1232 cons_key_tuple,key_comp_tuple
1233 >::compare(
1234 x.composite_key.key_extractors(),x.value,
1235 detail::make_cons_stdtuple(y),key_comps());
1236 }
1237
1238 template<typename CompositeKey,typename... Values>
1239 bool operator()(
1240 const std::tuple<Values...>& x,
1241 const composite_key_result<CompositeKey>& y)const
1242 {
1243 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1244 typedef typename CompositeKey::value_type value_type;
1245 typedef std::tuple<Values...> key_tuple;
1246 typedef typename detail::cons_stdtuple_ctor<
1247 key_tuple>::result_type cons_key_tuple;
1248
1249 BOOST_STATIC_ASSERT(
1250 std::tuple_size<key_tuple>::value<=
1251 static_cast<std::size_t>(tuples::length<key_comp_tuple>::value)||
1252 tuples::length<key_extractor_tuple>::value<=
1253 tuples::length<key_comp_tuple>::value);
1254
1255 return detail::compare_ckey_cval<
1256 key_extractor_tuple,value_type,
1257 cons_key_tuple,key_comp_tuple
1258 >::compare(
1259 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
1260 y.value,key_comps());
1261 }
1262 #endif
1263 };
1264
1265 /* composite_key_hash */
1266
1267 template
1268 <
1269 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash)
1270 >
1271 struct composite_key_hash:
1272 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)>
1273 {
1274 private:
1275 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> super;
1276
1277 public:
1278 typedef super key_hasher_tuple;
1279
1280 composite_key_hash(
1281 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)):
1282 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
1283 {}
1284
1285 composite_key_hash(const key_hasher_tuple& x):super(x){}
1286
1287 const key_hasher_tuple& key_hash_functions()const{return *this;}
1288 key_hasher_tuple& key_hash_functions(){return *this;}
1289
1290 template<typename CompositeKey>
1291 std::size_t operator()(const composite_key_result<CompositeKey> & x)const
1292 {
1293 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1294 typedef typename CompositeKey::value_type value_type;
1295
1296 BOOST_STATIC_ASSERT(
1297 tuples::length<key_extractor_tuple>::value==
1298 tuples::length<key_hasher_tuple>::value);
1299
1300 return detail::hash_ckey<
1301 key_extractor_tuple,value_type,
1302 key_hasher_tuple
1303 >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions());
1304 }
1305
1306 template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)>
1307 std::size_t operator()(
1308 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const
1309 {
1310 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1311
1312 BOOST_STATIC_ASSERT(
1313 tuples::length<key_tuple>::value==
1314 tuples::length<key_hasher_tuple>::value);
1315
1316 return detail::hash_cval<
1317 key_tuple,key_hasher_tuple
1318 >::hash(x,key_hash_functions());
1319 }
1320
1321 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
1322 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1323 template<typename... Values>
1324 std::size_t operator()(const std::tuple<Values...>& x)const
1325 {
1326 typedef std::tuple<Values...> key_tuple;
1327 typedef typename detail::cons_stdtuple_ctor<
1328 key_tuple>::result_type cons_key_tuple;
1329
1330 BOOST_STATIC_ASSERT(
1331 std::tuple_size<key_tuple>::value==
1332 static_cast<std::size_t>(tuples::length<key_hasher_tuple>::value));
1333
1334 return detail::hash_cval<
1335 cons_key_tuple,key_hasher_tuple
1336 >::hash(detail::make_cons_stdtuple(x),key_hash_functions());
1337 }
1338 #endif
1339 };
1340
1341 /* Instantiations of the former functors with "natural" basic components:
1342 * composite_key_result_equal_to uses std::equal_to of the values.
1343 * composite_key_result_less uses std::less.
1344 * composite_key_result_greater uses std::greater.
1345 * composite_key_result_hash uses boost::hash.
1346 */
1347
1348 #define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \
1349 composite_key_equal_to< \
1350 BOOST_MULTI_INDEX_CK_ENUM( \
1351 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1352 /* the argument is a PP list */ \
1353 (detail::nth_composite_key_equal_to, \
1354 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1355 BOOST_PP_NIL))) \
1356 >
1357
1358 template<typename CompositeKeyResult>
1359 struct composite_key_result_equal_to:
1360 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1361 BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
1362 {
1363 private:
1364 typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super;
1365
1366 public:
1367 typedef CompositeKeyResult first_argument_type;
1368 typedef first_argument_type second_argument_type;
1369 typedef bool result_type;
1370
1371 using super::operator();
1372 };
1373
1374 #define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \
1375 composite_key_compare< \
1376 BOOST_MULTI_INDEX_CK_ENUM( \
1377 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1378 /* the argument is a PP list */ \
1379 (detail::nth_composite_key_less, \
1380 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1381 BOOST_PP_NIL))) \
1382 >
1383
1384 template<typename CompositeKeyResult>
1385 struct composite_key_result_less:
1386 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1387 BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
1388 {
1389 private:
1390 typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super;
1391
1392 public:
1393 typedef CompositeKeyResult first_argument_type;
1394 typedef first_argument_type second_argument_type;
1395 typedef bool result_type;
1396
1397 using super::operator();
1398 };
1399
1400 #define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \
1401 composite_key_compare< \
1402 BOOST_MULTI_INDEX_CK_ENUM( \
1403 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1404 /* the argument is a PP list */ \
1405 (detail::nth_composite_key_greater, \
1406 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1407 BOOST_PP_NIL))) \
1408 >
1409
1410 template<typename CompositeKeyResult>
1411 struct composite_key_result_greater:
1412 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1413 BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
1414 {
1415 private:
1416 typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super;
1417
1418 public:
1419 typedef CompositeKeyResult first_argument_type;
1420 typedef first_argument_type second_argument_type;
1421 typedef bool result_type;
1422
1423 using super::operator();
1424 };
1425
1426 #define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \
1427 composite_key_hash< \
1428 BOOST_MULTI_INDEX_CK_ENUM( \
1429 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1430 /* the argument is a PP list */ \
1431 (detail::nth_composite_key_hash, \
1432 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1433 BOOST_PP_NIL))) \
1434 >
1435
1436 template<typename CompositeKeyResult>
1437 struct composite_key_result_hash:
1438 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1439 BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
1440 {
1441 private:
1442 typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super;
1443
1444 public:
1445 typedef CompositeKeyResult argument_type;
1446 typedef std::size_t result_type;
1447
1448 using super::operator();
1449 };
1450
1451 } /* namespace multi_index */
1452
1453 } /* namespace boost */
1454
1455 /* Specializations of std::equal_to, std::less, std::greater and boost::hash
1456 * for composite_key_results enabling interoperation with tuples of values.
1457 */
1458
1459 namespace std{
1460
1461 template<typename CompositeKey>
1462 struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >:
1463 boost::multi_index::composite_key_result_equal_to<
1464 boost::multi_index::composite_key_result<CompositeKey>
1465 >
1466 {
1467 };
1468
1469 template<typename CompositeKey>
1470 struct less<boost::multi_index::composite_key_result<CompositeKey> >:
1471 boost::multi_index::composite_key_result_less<
1472 boost::multi_index::composite_key_result<CompositeKey>
1473 >
1474 {
1475 };
1476
1477 template<typename CompositeKey>
1478 struct greater<boost::multi_index::composite_key_result<CompositeKey> >:
1479 boost::multi_index::composite_key_result_greater<
1480 boost::multi_index::composite_key_result<CompositeKey>
1481 >
1482 {
1483 };
1484
1485 } /* namespace std */
1486
1487 namespace boost{
1488
1489 template<typename CompositeKey>
1490 struct hash<boost::multi_index::composite_key_result<CompositeKey> >:
1491 boost::multi_index::composite_key_result_hash<
1492 boost::multi_index::composite_key_result<CompositeKey>
1493 >
1494 {
1495 };
1496
1497 } /* namespace boost */
1498
1499 #undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
1500 #undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
1501 #undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
1502 #undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
1503 #undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS
1504 #undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO
1505 #undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR
1506 #undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N
1507 #undef BOOST_MULTI_INDEX_CK_CTOR_ARG
1508 #undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM
1509 #undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS
1510 #undef BOOST_MULTI_INDEX_CK_ENUM
1511 #undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE
1512
1513 #endif