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)
6 * See http://www.boost.org/libs/multi_index for library home page.
9 #ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
10 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
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>
34 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
35 #include <boost/ref.hpp>
38 #if !defined(BOOST_NO_SFINAE)
39 #include <boost/type_traits/is_convertible.hpp>
42 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
43 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
44 #include <boost/multi_index/detail/cons_stdtuple.hpp>
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
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.
64 #if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE)
65 #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10
68 /* maximum number of key extractors in a composite key */
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
74 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10
77 /* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
79 #define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \
80 BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data)
82 /* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
84 #define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \
85 BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param)
88 * otherwise -> textn=tuples::null_type
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)
94 /* const textn& kn=textn() */
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)()
99 /* typename list(0)<list(1),n>::type */
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 \
108 template<class T> class reference_wrapper; /* fwd decl. */
110 namespace multi_index{
114 /* n-th key extractor of a composite key */
116 template<typename CompositeKey,int N>
117 struct nth_key_from_value
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>
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.
132 #define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \
133 template<typename KeyFromValue> \
134 struct BOOST_PP_CAT(key_,name) \
136 typedef functor<typename KeyFromValue::result_type> type; \
140 struct BOOST_PP_CAT(key_,name)<tuples::null_type> \
142 typedef tuples::null_type type; \
145 template<typename CompositeKey,int N> \
146 struct BOOST_PP_CAT(nth_composite_key_,name) \
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; \
152 /* nth_composite_key_equal_to
153 * nth_composite_key_less
154 * nth_composite_key_greater
155 * nth_composite_key_hash
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)
163 /* used for defining equality and comparison ops of composite_key_result */
165 #define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text
167 struct generic_operator_equal
169 template<typename T,typename Q>
170 bool operator()(const T& x,const Q& y)const{return x==y;}
174 BOOST_MULTI_INDEX_CK_ENUM(
175 BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
176 detail::generic_operator_equal)> generic_operator_equal_tuple;
178 struct generic_operator_less
180 template<typename T,typename Q>
181 bool operator()(const T& x,const Q& y)const{return x<y;}
185 BOOST_MULTI_INDEX_CK_ENUM(
186 BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
187 detail::generic_operator_less)> generic_operator_less_tuple;
189 /* Metaprogramming machinery for implementing equality, comparison and
190 * hashing operations of composite_key_result.
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.
200 typename KeyCons1,typename Value1,
201 typename KeyCons2, typename Value2,
204 struct equal_ckey_ckey; /* fwd decl. */
208 typename KeyCons1,typename Value1,
209 typename KeyCons2, typename Value2,
212 struct equal_ckey_ckey_terminal
215 const KeyCons1&,const Value1&,
216 const KeyCons2&,const Value2&,
225 typename KeyCons1,typename Value1,
226 typename KeyCons2, typename Value2,
229 struct equal_ckey_ckey_normal
232 const KeyCons1& c0,const Value1& v0,
233 const KeyCons2& c1,const Value2& v1,
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());
247 typename KeyCons1,typename Value1,
248 typename KeyCons2, typename Value2,
251 struct equal_ckey_ckey:
254 is_same<KeyCons1,tuples::null_type>,
255 is_same<KeyCons2,tuples::null_type>
257 equal_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>,
258 equal_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>
265 typename KeyCons,typename Value,
266 typename ValCons,typename EqualCons
268 struct equal_ckey_cval; /* fwd decl. */
272 typename KeyCons,typename Value,
273 typename ValCons,typename EqualCons
275 struct equal_ckey_cval_terminal
278 const KeyCons&,const Value&,const ValCons&,const EqualCons&)
284 const ValCons&,const KeyCons&,const Value&,const EqualCons&)
292 typename KeyCons,typename Value,
293 typename ValCons,typename EqualCons
295 struct equal_ckey_cval_normal
298 const KeyCons& c,const Value& v,const ValCons& vc,
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());
310 const ValCons& vc,const KeyCons& c,const Value& v,
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());
324 typename KeyCons,typename Value,
325 typename ValCons,typename EqualCons
327 struct equal_ckey_cval:
330 is_same<KeyCons,tuples::null_type>,
331 is_same<ValCons,tuples::null_type>
333 equal_ckey_cval_terminal<KeyCons,Value,ValCons,EqualCons>,
334 equal_ckey_cval_normal<KeyCons,Value,ValCons,EqualCons>
341 typename KeyCons1,typename Value1,
342 typename KeyCons2, typename Value2,
345 struct compare_ckey_ckey; /* fwd decl. */
349 typename KeyCons1,typename Value1,
350 typename KeyCons2, typename Value2,
353 struct compare_ckey_ckey_terminal
356 const KeyCons1&,const Value1&,
357 const KeyCons2&,const Value2&,
366 typename KeyCons1,typename Value1,
367 typename KeyCons2, typename Value2,
370 struct compare_ckey_ckey_normal
373 const KeyCons1& c0,const Value1& v0,
374 const KeyCons2& c1,const Value2& v1,
375 const CompareCons& comp)
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());
389 typename KeyCons1,typename Value1,
390 typename KeyCons2, typename Value2,
393 struct compare_ckey_ckey:
396 is_same<KeyCons1,tuples::null_type>,
397 is_same<KeyCons2,tuples::null_type>
399 compare_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>,
400 compare_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>
407 typename KeyCons,typename Value,
408 typename ValCons,typename CompareCons
410 struct compare_ckey_cval; /* fwd decl. */
414 typename KeyCons,typename Value,
415 typename ValCons,typename CompareCons
417 struct compare_ckey_cval_terminal
420 const KeyCons&,const Value&,const ValCons&,const CompareCons&)
426 const ValCons&,const KeyCons&,const Value&,const CompareCons&)
434 typename KeyCons,typename Value,
435 typename ValCons,typename CompareCons
437 struct compare_ckey_cval_normal
440 const KeyCons& c,const Value& v,const ValCons& vc,
441 const CompareCons& comp)
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());
453 const ValCons& vc,const KeyCons& c,const Value& v,
454 const CompareCons& comp)
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());
468 typename KeyCons,typename Value,
469 typename ValCons,typename CompareCons
471 struct compare_ckey_cval:
474 is_same<KeyCons,tuples::null_type>,
475 is_same<ValCons,tuples::null_type>
477 compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>,
478 compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons>
483 template<typename KeyCons,typename Value,typename HashCons>
484 struct hash_ckey; /* fwd decl. */
486 template<typename KeyCons,typename Value,typename HashCons>
487 struct hash_ckey_terminal
489 static std::size_t hash(
490 const KeyCons&,const Value&,const HashCons&,std::size_t carry)
496 template<typename KeyCons,typename Value,typename HashCons>
497 struct hash_ckey_normal
499 static std::size_t hash(
500 const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0)
502 /* same hashing formula as boost::hash_combine */
504 carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2);
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);
512 template<typename KeyCons,typename Value,typename HashCons>
515 is_same<KeyCons,tuples::null_type>,
516 hash_ckey_terminal<KeyCons,Value,HashCons>,
517 hash_ckey_normal<KeyCons,Value,HashCons>
522 template<typename ValCons,typename HashCons>
523 struct hash_cval; /* fwd decl. */
525 template<typename ValCons,typename HashCons>
526 struct hash_cval_terminal
528 static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry)
534 template<typename ValCons,typename HashCons>
535 struct hash_cval_normal
537 static std::size_t hash(
538 const ValCons& vc,const HashCons& h,std::size_t carry=0)
540 carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2);
542 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
543 BOOST_DEDUCED_TYPENAME HashCons::tail_type
544 >::hash(vc.get_tail(),h.get_tail(),carry);
548 template<typename ValCons,typename HashCons>
551 is_same<ValCons,tuples::null_type>,
552 hash_cval_terminal<ValCons,HashCons>,
553 hash_cval_normal<ValCons,HashCons>
558 } /* namespace multi_index::detail */
560 /* composite_key_result */
562 #if defined(BOOST_MSVC)
563 #pragma warning(push)
564 #pragma warning(disable:4512)
567 template<typename CompositeKey>
568 struct composite_key_result
570 typedef CompositeKey composite_key_type;
571 typedef typename composite_key_type::value_type value_type;
573 composite_key_result(
574 const composite_key_type& composite_key_,const value_type& value_):
575 composite_key(composite_key_),value(value_)
578 const composite_key_type& composite_key;
579 const value_type& value;
582 #if defined(BOOST_MSVC)
590 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
592 struct composite_key:
593 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)>
596 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super;
599 typedef super key_extractor_tuple;
600 typedef Value value_type;
601 typedef composite_key_result<composite_key> result_type;
604 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)):
605 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
608 composite_key(const key_extractor_tuple& x):super(x){}
610 const key_extractor_tuple& key_extractors()const{return *this;}
611 key_extractor_tuple& key_extractors(){return *this;}
613 template<typename ChainedPtr>
615 #if !defined(BOOST_NO_SFINAE)
617 is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
622 operator()(const ChainedPtr& x)const
624 return operator()(*x);
627 result_type operator()(const value_type& x)const
629 return result_type(*this,x);
632 result_type operator()(const reference_wrapper<const value_type>& x)const
634 return result_type(*this,x.get());
637 result_type operator()(const reference_wrapper<value_type>& x)const
639 return result_type(*this,x.get());
643 /* comparison operators */
647 template<typename CompositeKey1,typename CompositeKey2>
648 inline bool operator==(
649 const composite_key_result<CompositeKey1>& x,
650 const composite_key_result<CompositeKey2>& y)
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;
658 tuples::length<key_extractor_tuple1>::value==
659 tuples::length<key_extractor_tuple2>::value);
661 return detail::equal_ckey_ckey<
662 key_extractor_tuple1,value_type1,
663 key_extractor_tuple2,value_type2,
664 detail::generic_operator_equal_tuple
666 x.composite_key.key_extractors(),x.value,
667 y.composite_key.key_extractors(),y.value,
668 detail::generic_operator_equal_tuple());
672 typename CompositeKey,
673 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
675 inline bool operator==(
676 const composite_key_result<CompositeKey>& x,
677 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
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;
684 tuples::length<key_extractor_tuple>::value==
685 tuples::length<key_tuple>::value);
687 return detail::equal_ckey_cval<
688 key_extractor_tuple,value_type,
689 key_tuple,detail::generic_operator_equal_tuple
691 x.composite_key.key_extractors(),x.value,
692 y,detail::generic_operator_equal_tuple());
697 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
698 typename CompositeKey
700 inline bool operator==(
701 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
702 const composite_key_result<CompositeKey>& y)
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;
709 tuples::length<key_extractor_tuple>::value==
710 tuples::length<key_tuple>::value);
712 return detail::equal_ckey_cval<
713 key_extractor_tuple,value_type,
714 key_tuple,detail::generic_operator_equal_tuple
716 x,y.composite_key.key_extractors(),
717 y.value,detail::generic_operator_equal_tuple());
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)
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;
734 static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
735 std::tuple_size<key_tuple>::value);
737 return detail::equal_ckey_cval<
738 key_extractor_tuple,value_type,
739 cons_key_tuple,detail::generic_operator_equal_tuple
741 x.composite_key.key_extractors(),x.value,
742 detail::make_cons_stdtuple(y),detail::generic_operator_equal_tuple());
745 template<typename CompositeKey,typename... Values>
746 inline bool operator==(
747 const std::tuple<Values...>& x,
748 const composite_key_result<CompositeKey>& y)
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;
757 static_cast<std::size_t>(tuples::length<key_extractor_tuple>::value)==
758 std::tuple_size<key_tuple>::value);
760 return detail::equal_ckey_cval<
761 key_extractor_tuple,value_type,
762 cons_key_tuple,detail::generic_operator_equal_tuple
764 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
765 y.value,detail::generic_operator_equal_tuple());
771 template<typename CompositeKey1,typename CompositeKey2>
772 inline bool operator<(
773 const composite_key_result<CompositeKey1>& x,
774 const composite_key_result<CompositeKey2>& y)
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;
781 return detail::compare_ckey_ckey<
782 key_extractor_tuple1,value_type1,
783 key_extractor_tuple2,value_type2,
784 detail::generic_operator_less_tuple
786 x.composite_key.key_extractors(),x.value,
787 y.composite_key.key_extractors(),y.value,
788 detail::generic_operator_less_tuple());
793 typename CompositeKey,
794 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
796 inline bool operator<(
797 const composite_key_result<CompositeKey>& x,
798 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
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;
804 return detail::compare_ckey_cval<
805 key_extractor_tuple,value_type,
806 key_tuple,detail::generic_operator_less_tuple
808 x.composite_key.key_extractors(),x.value,
809 y,detail::generic_operator_less_tuple());
814 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
815 typename CompositeKey
817 inline bool operator<(
818 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
819 const composite_key_result<CompositeKey>& y)
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;
825 return detail::compare_ckey_cval<
826 key_extractor_tuple,value_type,
827 key_tuple,detail::generic_operator_less_tuple
829 x,y.composite_key.key_extractors(),
830 y.value,detail::generic_operator_less_tuple());
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)
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;
846 return detail::compare_ckey_cval<
847 key_extractor_tuple,value_type,
848 cons_key_tuple,detail::generic_operator_less_tuple
850 x.composite_key.key_extractors(),x.value,
851 detail::make_cons_stdtuple(y),detail::generic_operator_less_tuple());
854 template<typename CompositeKey,typename... Values>
855 inline bool operator<(
856 const std::tuple<Values...>& x,
857 const composite_key_result<CompositeKey>& y)
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;
865 return detail::compare_ckey_cval<
866 key_extractor_tuple,value_type,
867 cons_key_tuple,detail::generic_operator_less_tuple
869 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
870 y.value,detail::generic_operator_less_tuple());
874 /* rest of comparison operators */
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) \
882 template<t1,t2> inline bool operator>(const a1& x,const a2& y) \
887 template<t1,t2> inline bool operator>=(const a1& x,const a2& y) \
892 template<t1,t2> inline bool operator<=(const a1& x,const a2& y) \
897 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
898 typename CompositeKey1,
899 typename CompositeKey2,
900 composite_key_result<CompositeKey1>,
901 composite_key_result<CompositeKey2>
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)>
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>
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,
923 composite_key_result<CompositeKey>,
924 std::tuple<Values...>
927 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
928 typename CompositeKey,
930 std::tuple<Values...>,
931 composite_key_result<CompositeKey>
935 /* composite_key_equal_to */
939 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred)
941 struct composite_key_equal_to:
942 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)>
945 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super;
948 typedef super key_eq_tuple;
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))
955 composite_key_equal_to(const key_eq_tuple& x):super(x){}
957 const key_eq_tuple& key_eqs()const{return *this;}
958 key_eq_tuple& key_eqs(){return *this;}
960 template<typename CompositeKey1,typename CompositeKey2>
962 const composite_key_result<CompositeKey1> & x,
963 const composite_key_result<CompositeKey2> & y)const
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;
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);
976 return detail::equal_ckey_ckey<
977 key_extractor_tuple1,value_type1,
978 key_extractor_tuple2,value_type2,
981 x.composite_key.key_extractors(),x.value,
982 y.composite_key.key_extractors(),y.value,
988 typename CompositeKey,
989 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
992 const composite_key_result<CompositeKey>& x,
993 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
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;
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);
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());
1013 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1014 typename CompositeKey
1017 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1018 const composite_key_result<CompositeKey>& y)const
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;
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);
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());
1036 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
1037 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1038 template<typename CompositeKey,typename... Values>
1040 const composite_key_result<CompositeKey>& x,
1041 const std::tuple<Values...>& y)const
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;
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);
1055 return detail::equal_ckey_cval<
1056 key_extractor_tuple,value_type,
1057 cons_key_tuple,key_eq_tuple
1059 x.composite_key.key_extractors(),x.value,
1060 detail::make_cons_stdtuple(y),key_eqs());
1063 template<typename CompositeKey,typename... Values>
1065 const std::tuple<Values...>& x,
1066 const composite_key_result<CompositeKey>& y)const
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;
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));
1080 return detail::equal_ckey_cval<
1081 key_extractor_tuple,value_type,
1082 cons_key_tuple,key_eq_tuple
1084 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
1090 /* composite_key_compare */
1094 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare)
1096 struct composite_key_compare:
1097 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)>
1100 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> super;
1103 typedef super key_comp_tuple;
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))
1110 composite_key_compare(const key_comp_tuple& x):super(x){}
1112 const key_comp_tuple& key_comps()const{return *this;}
1113 key_comp_tuple& key_comps(){return *this;}
1115 template<typename CompositeKey1,typename CompositeKey2>
1117 const composite_key_result<CompositeKey1> & x,
1118 const composite_key_result<CompositeKey2> & y)const
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;
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);
1131 return detail::compare_ckey_ckey<
1132 key_extractor_tuple1,value_type1,
1133 key_extractor_tuple2,value_type2,
1136 x.composite_key.key_extractors(),x.value,
1137 y.composite_key.key_extractors(),y.value,
1141 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
1142 template<typename CompositeKey,typename Value>
1144 const composite_key_result<CompositeKey>& x,
1145 const Value& y)const
1147 return operator()(x,boost::make_tuple(boost::cref(y)));
1153 typename CompositeKey,
1154 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
1157 const composite_key_result<CompositeKey>& x,
1158 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
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;
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);
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());
1176 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
1177 template<typename Value,typename CompositeKey>
1180 const composite_key_result<CompositeKey>& y)const
1182 return operator()(boost::make_tuple(boost::cref(x)),y);
1188 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1189 typename CompositeKey
1192 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1193 const composite_key_result<CompositeKey>& y)const
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;
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);
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());
1211 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
1212 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1213 template<typename CompositeKey,typename... Values>
1215 const composite_key_result<CompositeKey>& x,
1216 const std::tuple<Values...>& y)const
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;
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));
1230 return detail::compare_ckey_cval<
1231 key_extractor_tuple,value_type,
1232 cons_key_tuple,key_comp_tuple
1234 x.composite_key.key_extractors(),x.value,
1235 detail::make_cons_stdtuple(y),key_comps());
1238 template<typename CompositeKey,typename... Values>
1240 const std::tuple<Values...>& x,
1241 const composite_key_result<CompositeKey>& y)const
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;
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);
1255 return detail::compare_ckey_cval<
1256 key_extractor_tuple,value_type,
1257 cons_key_tuple,key_comp_tuple
1259 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
1260 y.value,key_comps());
1265 /* composite_key_hash */
1269 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash)
1271 struct composite_key_hash:
1272 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)>
1275 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> super;
1278 typedef super key_hasher_tuple;
1281 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)):
1282 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
1285 composite_key_hash(const key_hasher_tuple& x):super(x){}
1287 const key_hasher_tuple& key_hash_functions()const{return *this;}
1288 key_hasher_tuple& key_hash_functions(){return *this;}
1290 template<typename CompositeKey>
1291 std::size_t operator()(const composite_key_result<CompositeKey> & x)const
1293 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1294 typedef typename CompositeKey::value_type value_type;
1296 BOOST_STATIC_ASSERT(
1297 tuples::length<key_extractor_tuple>::value==
1298 tuples::length<key_hasher_tuple>::value);
1300 return detail::hash_ckey<
1301 key_extractor_tuple,value_type,
1303 >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions());
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
1310 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1312 BOOST_STATIC_ASSERT(
1313 tuples::length<key_tuple>::value==
1314 tuples::length<key_hasher_tuple>::value);
1316 return detail::hash_cval<
1317 key_tuple,key_hasher_tuple
1318 >::hash(x,key_hash_functions());
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
1326 typedef std::tuple<Values...> key_tuple;
1327 typedef typename detail::cons_stdtuple_ctor<
1328 key_tuple>::result_type cons_key_tuple;
1330 BOOST_STATIC_ASSERT(
1331 std::tuple_size<key_tuple>::value==
1332 static_cast<std::size_t>(tuples::length<key_hasher_tuple>::value));
1334 return detail::hash_cval<
1335 cons_key_tuple,key_hasher_tuple
1336 >::hash(detail::make_cons_stdtuple(x),key_hash_functions());
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.
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, \
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
1364 typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super;
1367 typedef CompositeKeyResult first_argument_type;
1368 typedef first_argument_type second_argument_type;
1369 typedef bool result_type;
1371 using super::operator();
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, \
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
1390 typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super;
1393 typedef CompositeKeyResult first_argument_type;
1394 typedef first_argument_type second_argument_type;
1395 typedef bool result_type;
1397 using super::operator();
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, \
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
1416 typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super;
1419 typedef CompositeKeyResult first_argument_type;
1420 typedef first_argument_type second_argument_type;
1421 typedef bool result_type;
1423 using super::operator();
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, \
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
1442 typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super;
1445 typedef CompositeKeyResult argument_type;
1446 typedef std::size_t result_type;
1448 using super::operator();
1451 } /* namespace multi_index */
1453 } /* namespace boost */
1455 /* Specializations of std::equal_to, std::less, std::greater and boost::hash
1456 * for composite_key_results enabling interoperation with tuples of values.
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>
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>
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>
1485 } /* namespace std */
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>
1497 } /* namespace boost */
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