williamr@2: /* Copyright 2003-2006 Joaquín M López Muñoz. williamr@2: * Distributed under the Boost Software License, Version 1.0. williamr@2: * (See accompanying file LICENSE_1_0.txt or copy at williamr@2: * http://www.boost.org/LICENSE_1_0.txt) williamr@2: * williamr@2: * See http://www.boost.org/libs/multi_index for library home page. williamr@2: */ williamr@2: williamr@2: #ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP williamr@2: #define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP williamr@2: williamr@2: #if defined(_MSC_VER)&&(_MSC_VER>=1200) williamr@2: #pragma once williamr@2: #endif williamr@2: williamr@2: #include /* keep it first to prevent nasty warns in MSVC */ williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) williamr@2: #include williamr@2: #endif williamr@2: williamr@2: #if !defined(BOOST_NO_SFINAE) williamr@2: #include williamr@2: #endif williamr@2: williamr@2: /* A composite key stores n key extractors and "computes" the williamr@2: * result on a given value as a packed reference to the value and williamr@2: * the composite key itself. Actual invocations to the component williamr@2: * key extractors are lazily performed when executing an operation williamr@2: * on composite_key results (equality, comparison, hashing.) williamr@2: * As the other key extractors in Boost.MultiIndex, composite_key williamr@2: * is overloaded to work on chained pointers to T and reference_wrappers williamr@2: * of T. williamr@2: */ williamr@2: williamr@2: /* This user_definable macro limits the number of elements of a composite williamr@2: * key; useful for shortening resulting symbol names (MSVC++ 6.0, for williamr@2: * instance has problems coping with very long symbol names.) williamr@2: * NB: This cannot exceed the maximum number of arguments of williamr@2: * boost::tuple. In Boost 1.32, the limit is 10. williamr@2: */ williamr@2: williamr@2: #if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE) williamr@2: #if defined(BOOST_MSVC)&&(BOOST_MSVC<1300) williamr@2: #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 5 williamr@2: #else williamr@2: #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10 williamr@2: #endif williamr@2: #endif williamr@2: williamr@2: /* maximum number of key extractors in a composite key */ williamr@2: williamr@2: #if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */ williamr@2: #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \ williamr@2: BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE williamr@2: #else williamr@2: #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10 williamr@2: #endif williamr@2: williamr@2: /* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \ williamr@2: BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data) williamr@2: williamr@2: /* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \ williamr@2: BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param) williamr@2: williamr@2: /* if n==0 -> text0 williamr@2: * otherwise -> textn=tuples::null_type williamr@2: */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \ williamr@2: typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type) williamr@2: williamr@2: /* const textn& kn=textn() */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \ williamr@2: const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)() williamr@2: williamr@2: /* typename list(0)::type */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \ williamr@2: BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \ williamr@2: BOOST_PP_LIST_AT(list,1),n \ williamr@2: >::type williamr@2: williamr@2: namespace boost{ williamr@2: williamr@2: template class reference_wrapper; /* fwd decl. */ williamr@2: template struct hash; /* fwd decl. */ williamr@2: williamr@2: namespace multi_index{ williamr@2: williamr@2: namespace detail{ williamr@2: williamr@2: /* n-th key extractor of a composite key */ williamr@2: williamr@2: template williamr@2: struct nth_key_from_value williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename prevent_eti< williamr@2: tuples::element, williamr@2: typename mpl::eval_if_c< williamr@2: N::value, williamr@2: tuples::element, williamr@2: mpl::identity williamr@2: >::type williamr@2: >::type type; williamr@2: }; williamr@2: williamr@2: /* nth_composite_key_##name::type yields williamr@2: * functor >, or tuples::null_type williamr@2: * if N exceeds the length of the composite key. williamr@2: */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \ williamr@2: template \ williamr@2: struct BOOST_PP_CAT(key_,name) \ williamr@2: { \ williamr@2: typedef functor type; \ williamr@2: }; \ williamr@2: \ williamr@2: template<> \ williamr@2: struct BOOST_PP_CAT(key_,name) \ williamr@2: { \ williamr@2: typedef tuples::null_type type; \ williamr@2: }; \ williamr@2: \ williamr@2: template \ williamr@2: struct BOOST_PP_CAT(nth_composite_key_,name) \ williamr@2: { \ williamr@2: typedef typename nth_key_from_value::type key_from_value; \ williamr@2: typedef typename BOOST_PP_CAT(key_,name)::type type; \ williamr@2: }; williamr@2: williamr@2: /* nth_composite_key_equal_to williamr@2: * nth_composite_key_less williamr@2: * nth_composite_key_greater williamr@2: * nth_composite_key_hash williamr@2: */ williamr@2: williamr@2: BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to) williamr@2: BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less) williamr@2: BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater) williamr@2: BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash) williamr@2: williamr@2: /* used for defining equality and comparison ops of composite_key_result */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text williamr@2: williamr@2: struct generic_operator_equal williamr@2: { williamr@2: template williamr@2: bool operator()(const T& x,const Q& y)const{return x==y;} williamr@2: }; williamr@2: williamr@2: typedef tuple< williamr@2: BOOST_MULTI_INDEX_CK_ENUM( williamr@2: BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO, williamr@2: detail::generic_operator_equal)> generic_operator_equal_tuple; williamr@2: williamr@2: struct generic_operator_less williamr@2: { williamr@2: template williamr@2: bool operator()(const T& x,const Q& y)const{return x generic_operator_less_tuple; williamr@2: williamr@2: /* Metaprogramming machinery for implementing equality, comparison and williamr@2: * hashing operations of composite_key_result. williamr@2: * williamr@2: * equal_* checks for equality between composite_key_results and williamr@2: * between those and tuples, accepting a tuple of basic equality functors. williamr@2: * compare_* does lexicographical comparison. williamr@2: * hash_* computes a combination of elementwise hash values. williamr@2: */ williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename EqualCons williamr@2: > williamr@2: struct equal_ckey_ckey; /* fwd decl. */ williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename EqualCons williamr@2: > williamr@2: struct equal_ckey_ckey_terminal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons1&,const Value1&, williamr@2: const KeyCons2&,const Value2&, williamr@2: const EqualCons&) williamr@2: { williamr@2: return true; williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename EqualCons williamr@2: > williamr@2: struct equal_ckey_ckey_normal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons1& c0,const Value1& v0, williamr@2: const KeyCons2& c1,const Value2& v1, williamr@2: const EqualCons& eq) williamr@2: { williamr@2: if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false; williamr@2: return equal_ckey_ckey< williamr@2: BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, williamr@2: BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, williamr@2: BOOST_DEDUCED_TYPENAME EqualCons::tail_type williamr@2: >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail()); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename EqualCons williamr@2: > williamr@2: struct equal_ckey_ckey: williamr@2: mpl::if_< williamr@2: mpl::or_< williamr@2: is_same, williamr@2: is_same williamr@2: >, williamr@2: equal_ckey_ckey_terminal, williamr@2: equal_ckey_ckey_normal williamr@2: >::type williamr@2: { williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename EqualCons williamr@2: > williamr@2: struct equal_ckey_cval; /* fwd decl. */ williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename EqualCons williamr@2: > williamr@2: struct equal_ckey_cval_terminal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons&,const Value&,const ValCons&,const EqualCons&) williamr@2: { williamr@2: return true; williamr@2: } williamr@2: williamr@2: static bool compare( williamr@2: const ValCons&,const KeyCons&,const Value&,const EqualCons&) williamr@2: { williamr@2: return true; williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename EqualCons williamr@2: > williamr@2: struct equal_ckey_cval_normal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons& c,const Value& v,const ValCons& vc, williamr@2: const EqualCons& eq) williamr@2: { williamr@2: if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false; williamr@2: return equal_ckey_cval< williamr@2: BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, williamr@2: BOOST_DEDUCED_TYPENAME ValCons::tail_type, williamr@2: BOOST_DEDUCED_TYPENAME EqualCons::tail_type williamr@2: >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail()); williamr@2: } williamr@2: williamr@2: static bool compare( williamr@2: const ValCons& vc,const KeyCons& c,const Value& v, williamr@2: const EqualCons& eq) williamr@2: { williamr@2: if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false; williamr@2: return equal_ckey_cval< williamr@2: BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, williamr@2: BOOST_DEDUCED_TYPENAME ValCons::tail_type, williamr@2: BOOST_DEDUCED_TYPENAME EqualCons::tail_type williamr@2: >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail()); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename EqualCons williamr@2: > williamr@2: struct equal_ckey_cval: williamr@2: mpl::if_< williamr@2: mpl::or_< williamr@2: is_same, williamr@2: is_same williamr@2: >, williamr@2: equal_ckey_cval_terminal, williamr@2: equal_ckey_cval_normal williamr@2: >::type williamr@2: { williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename CompareCons williamr@2: > williamr@2: struct compare_ckey_ckey; /* fwd decl. */ williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename CompareCons williamr@2: > williamr@2: struct compare_ckey_ckey_terminal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons1&,const Value1&, williamr@2: const KeyCons2&,const Value2&, williamr@2: const CompareCons&) williamr@2: { williamr@2: return false; williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename CompareCons williamr@2: > williamr@2: struct compare_ckey_ckey_normal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons1& c0,const Value1& v0, williamr@2: const KeyCons2& c1,const Value2& v1, williamr@2: const CompareCons& comp) williamr@2: { williamr@2: if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true; williamr@2: if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false; williamr@2: return compare_ckey_ckey< williamr@2: BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, williamr@2: BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, williamr@2: BOOST_DEDUCED_TYPENAME CompareCons::tail_type williamr@2: >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail()); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons1,typename Value1, williamr@2: typename KeyCons2, typename Value2, williamr@2: typename CompareCons williamr@2: > williamr@2: struct compare_ckey_ckey: williamr@2: mpl::if_< williamr@2: mpl::or_< williamr@2: is_same, williamr@2: is_same williamr@2: >, williamr@2: compare_ckey_ckey_terminal, williamr@2: compare_ckey_ckey_normal williamr@2: >::type williamr@2: { williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename CompareCons williamr@2: > williamr@2: struct compare_ckey_cval; /* fwd decl. */ williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename CompareCons williamr@2: > williamr@2: struct compare_ckey_cval_terminal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons&,const Value&,const ValCons&,const CompareCons&) williamr@2: { williamr@2: return false; williamr@2: } williamr@2: williamr@2: static bool compare( williamr@2: const ValCons&,const KeyCons&,const Value&,const CompareCons&) williamr@2: { williamr@2: return false; williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename CompareCons williamr@2: > williamr@2: struct compare_ckey_cval_normal williamr@2: { williamr@2: static bool compare( williamr@2: const KeyCons& c,const Value& v,const ValCons& vc, williamr@2: const CompareCons& comp) williamr@2: { williamr@2: if(comp.get_head()(c.get_head()(v),vc.get_head()))return true; williamr@2: if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false; williamr@2: return compare_ckey_cval< williamr@2: BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, williamr@2: BOOST_DEDUCED_TYPENAME ValCons::tail_type, williamr@2: BOOST_DEDUCED_TYPENAME CompareCons::tail_type williamr@2: >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail()); williamr@2: } williamr@2: williamr@2: static bool compare( williamr@2: const ValCons& vc,const KeyCons& c,const Value& v, williamr@2: const CompareCons& comp) williamr@2: { williamr@2: if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true; williamr@2: if(comp.get_head()(c.get_head()(v),vc.get_head()))return false; williamr@2: return compare_ckey_cval< williamr@2: BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, williamr@2: BOOST_DEDUCED_TYPENAME ValCons::tail_type, williamr@2: BOOST_DEDUCED_TYPENAME CompareCons::tail_type williamr@2: >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail()); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: < williamr@2: typename KeyCons,typename Value, williamr@2: typename ValCons,typename CompareCons williamr@2: > williamr@2: struct compare_ckey_cval: williamr@2: mpl::if_< williamr@2: mpl::or_< williamr@2: is_same, williamr@2: is_same williamr@2: >, williamr@2: compare_ckey_cval_terminal, williamr@2: compare_ckey_cval_normal williamr@2: >::type williamr@2: { williamr@2: }; williamr@2: williamr@2: template williamr@2: struct hash_ckey; /* fwd decl. */ williamr@2: williamr@2: template williamr@2: struct hash_ckey_terminal williamr@2: { williamr@2: static std::size_t hash( williamr@2: const KeyCons&,const Value&,const HashCons&,std::size_t carry) williamr@2: { williamr@2: return carry; williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct hash_ckey_normal williamr@2: { williamr@2: static std::size_t hash( williamr@2: const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0) williamr@2: { williamr@2: /* same hashing formula as boost::hash_combine */ williamr@2: williamr@2: carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2); williamr@2: return hash_ckey< williamr@2: BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, williamr@2: BOOST_DEDUCED_TYPENAME HashCons::tail_type williamr@2: >::hash(c.get_tail(),v,h.get_tail(),carry); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct hash_ckey: williamr@2: mpl::if_< williamr@2: is_same, williamr@2: hash_ckey_terminal, williamr@2: hash_ckey_normal williamr@2: >::type williamr@2: { williamr@2: }; williamr@2: williamr@2: template williamr@2: struct hash_cval; /* fwd decl. */ williamr@2: williamr@2: template williamr@2: struct hash_cval_terminal williamr@2: { williamr@2: static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry) williamr@2: { williamr@2: return carry; williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct hash_cval_normal williamr@2: { williamr@2: static std::size_t hash( williamr@2: const ValCons& vc,const HashCons& h,std::size_t carry=0) williamr@2: { williamr@2: carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2); williamr@2: return hash_cval< williamr@2: BOOST_DEDUCED_TYPENAME ValCons::tail_type, williamr@2: BOOST_DEDUCED_TYPENAME HashCons::tail_type williamr@2: >::hash(vc.get_tail(),h.get_tail(),carry); williamr@2: } williamr@2: }; williamr@2: williamr@2: template williamr@2: struct hash_cval: williamr@2: mpl::if_< williamr@2: is_same, williamr@2: hash_cval_terminal, williamr@2: hash_cval_normal williamr@2: >::type williamr@2: { williamr@2: }; williamr@2: williamr@2: } /* namespace multi_index::detail */ williamr@2: williamr@2: /* composite_key_result */ williamr@2: williamr@2: template williamr@2: struct composite_key_result williamr@2: { williamr@2: typedef CompositeKey composite_key_type; williamr@2: typedef typename composite_key_type::value_type value_type; williamr@2: williamr@2: composite_key_result( williamr@2: const composite_key_type& composite_key_,const value_type& value_): williamr@2: composite_key(composite_key_),value(value_) williamr@2: {} williamr@2: williamr@2: const composite_key_type& composite_key; williamr@2: const value_type& value; williamr@2: }; williamr@2: williamr@2: /* composite_key */ williamr@2: williamr@2: /* NB. Some overloads of operator() have an extra dummy parameter int=0. williamr@2: * This disambiguator serves several purposes: williamr@2: * - Without it, MSVC++ 6.0 incorrectly regards some overloads as williamr@2: * specializations of a previous member function template. williamr@2: * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns williamr@2: * as if they have the same signature. williamr@2: * - If remove_const is broken due to lack of PTS, int=0 avoids the williamr@2: * declaration of memfuns with identical signature. williamr@2: */ williamr@2: williamr@2: template< williamr@2: typename Value, williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue) williamr@2: > williamr@2: struct composite_key: williamr@2: private tuple williamr@2: { williamr@2: private: williamr@2: typedef tuple super; williamr@2: williamr@2: public: williamr@2: typedef super key_extractor_tuple; williamr@2: typedef Value value_type; williamr@2: typedef composite_key_result result_type; williamr@2: williamr@2: composite_key( williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)): williamr@2: super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) williamr@2: {} williamr@2: williamr@2: composite_key(const key_extractor_tuple& x):super(x){} williamr@2: williamr@2: const key_extractor_tuple& key_extractors()const{return *this;} williamr@2: key_extractor_tuple& key_extractors(){return *this;} williamr@2: williamr@2: template williamr@2: williamr@2: #if !defined(BOOST_NO_SFINAE) williamr@2: typename disable_if< williamr@2: is_convertible,result_type>::type williamr@2: #else williamr@2: result_type williamr@2: #endif williamr@2: williamr@2: operator()(const ChainedPtr& x)const williamr@2: { williamr@2: return operator()(*x); williamr@2: } williamr@2: williamr@2: result_type operator()(const value_type& x)const williamr@2: { williamr@2: return result_type(*this,x); williamr@2: } williamr@2: williamr@2: result_type operator()(const reference_wrapper& x)const williamr@2: { williamr@2: return result_type(*this,x.get()); williamr@2: } williamr@2: williamr@2: result_type operator()(const reference_wrapper& x,int=0)const williamr@2: { williamr@2: return result_type(*this,x.get()); williamr@2: } williamr@2: }; williamr@2: williamr@2: /* comparison operators */ williamr@2: williamr@2: /* == */ williamr@2: williamr@2: template williamr@2: inline bool operator==( williamr@2: const composite_key_result& x, williamr@2: const composite_key_result& y) williamr@2: { williamr@2: typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; williamr@2: typedef typename CompositeKey1::value_type value_type1; williamr@2: typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; williamr@2: typedef typename CompositeKey2::value_type value_type2; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::equal_ckey_ckey< williamr@2: key_extractor_tuple1,value_type1, williamr@2: key_extractor_tuple2,value_type2, williamr@2: detail::generic_operator_equal_tuple williamr@2: >::compare( williamr@2: x.composite_key.key_extractors(),x.value, williamr@2: y.composite_key.key_extractors(),y.value, williamr@2: detail::generic_operator_equal_tuple()); williamr@2: } williamr@2: williamr@2: template< williamr@2: typename CompositeKey, williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) williamr@2: > williamr@2: inline bool operator==( williamr@2: const composite_key_result& x, williamr@2: const tuple& y) williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::equal_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,detail::generic_operator_equal_tuple williamr@2: >::compare( williamr@2: x.composite_key.key_extractors(),x.value, williamr@2: y,detail::generic_operator_equal_tuple()); williamr@2: } williamr@2: williamr@2: template williamr@2: < williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), williamr@2: typename CompositeKey williamr@2: > williamr@2: inline bool operator==( williamr@2: const tuple& x, williamr@2: const composite_key_result& y) williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::equal_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,detail::generic_operator_equal_tuple williamr@2: >::compare( williamr@2: x,y.composite_key.key_extractors(), williamr@2: y.value,detail::generic_operator_equal_tuple()); williamr@2: } williamr@2: williamr@2: /* < */ williamr@2: williamr@2: template williamr@2: inline bool operator<( williamr@2: const composite_key_result& x, williamr@2: const composite_key_result& y) williamr@2: { williamr@2: typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; williamr@2: typedef typename CompositeKey1::value_type value_type1; williamr@2: typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; williamr@2: typedef typename CompositeKey2::value_type value_type2; williamr@2: williamr@2: return detail::compare_ckey_ckey< williamr@2: key_extractor_tuple1,value_type1, williamr@2: key_extractor_tuple2,value_type2, williamr@2: detail::generic_operator_less_tuple williamr@2: >::compare( williamr@2: x.composite_key.key_extractors(),x.value, williamr@2: y.composite_key.key_extractors(),y.value, williamr@2: detail::generic_operator_less_tuple()); williamr@2: } williamr@2: williamr@2: template williamr@2: < williamr@2: typename CompositeKey, williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) williamr@2: > williamr@2: inline bool operator<( williamr@2: const composite_key_result& x, williamr@2: const tuple& y) williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: return detail::compare_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,detail::generic_operator_less_tuple williamr@2: >::compare( williamr@2: x.composite_key.key_extractors(),x.value, williamr@2: y,detail::generic_operator_less_tuple()); williamr@2: } williamr@2: williamr@2: template williamr@2: < williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), williamr@2: typename CompositeKey williamr@2: > williamr@2: inline bool operator<( williamr@2: const tuple& x, williamr@2: const composite_key_result& y) williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: return detail::compare_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,detail::generic_operator_less_tuple williamr@2: >::compare( williamr@2: x,y.composite_key.key_extractors(), williamr@2: y.value,detail::generic_operator_less_tuple()); williamr@2: } williamr@2: williamr@2: /* rest of comparison operators */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \ williamr@2: template inline bool operator!=(const a1& x,const a2& y) \ williamr@2: { \ williamr@2: return !(x==y); \ williamr@2: } \ williamr@2: \ williamr@2: template inline bool operator>(const a1& x,const a2& y) \ williamr@2: { \ williamr@2: return y inline bool operator>=(const a1& x,const a2& y) \ williamr@2: { \ williamr@2: return !(x inline bool operator<=(const a1& x,const a2& y) \ williamr@2: { \ williamr@2: return !(y, williamr@2: composite_key_result williamr@2: ) williamr@2: williamr@2: BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( williamr@2: typename CompositeKey, williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), williamr@2: composite_key_result, williamr@2: tuple williamr@2: ) williamr@2: williamr@2: BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), williamr@2: typename CompositeKey, williamr@2: tuple, williamr@2: composite_key_result williamr@2: ) williamr@2: williamr@2: /* composite_key_equal_to */ williamr@2: williamr@2: template williamr@2: < williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred) williamr@2: > williamr@2: struct composite_key_equal_to: williamr@2: private tuple williamr@2: { williamr@2: private: williamr@2: typedef tuple super; williamr@2: williamr@2: public: williamr@2: typedef super key_eq_tuple; williamr@2: williamr@2: composite_key_equal_to( williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)): williamr@2: super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) williamr@2: {} williamr@2: williamr@2: composite_key_equal_to(const key_eq_tuple& x):super(x){} williamr@2: williamr@2: const key_eq_tuple& key_eqs()const{return *this;} williamr@2: key_eq_tuple& key_eqs(){return *this;} williamr@2: williamr@2: template williamr@2: bool operator()( williamr@2: const composite_key_result & x, williamr@2: const composite_key_result & y)const williamr@2: { williamr@2: typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; williamr@2: typedef typename CompositeKey1::value_type value_type1; williamr@2: typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; williamr@2: typedef typename CompositeKey2::value_type value_type2; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value<= williamr@2: tuples::length::value&& williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::equal_ckey_ckey< williamr@2: key_extractor_tuple1,value_type1, williamr@2: key_extractor_tuple2,value_type2, williamr@2: key_eq_tuple williamr@2: >::compare( williamr@2: x.composite_key.key_extractors(),x.value, williamr@2: y.composite_key.key_extractors(),y.value, williamr@2: key_eqs()); williamr@2: } williamr@2: williamr@2: template williamr@2: < williamr@2: typename CompositeKey, williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) williamr@2: > williamr@2: bool operator()( williamr@2: const composite_key_result& x, williamr@2: const tuple& y)const williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value<= williamr@2: tuples::length::value&& williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::equal_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,key_eq_tuple williamr@2: >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs()); williamr@2: } williamr@2: williamr@2: template williamr@2: < williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), williamr@2: typename CompositeKey williamr@2: > williamr@2: bool operator()( williamr@2: const tuple& x, williamr@2: const composite_key_result& y)const williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value<= williamr@2: tuples::length::value&& williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::equal_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,key_eq_tuple williamr@2: >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs()); williamr@2: } williamr@2: }; williamr@2: williamr@2: /* composite_key_compare */ williamr@2: williamr@2: template williamr@2: < williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare) williamr@2: > williamr@2: struct composite_key_compare: williamr@2: private tuple williamr@2: { williamr@2: private: williamr@2: typedef tuple super; williamr@2: williamr@2: public: williamr@2: typedef super key_comp_tuple; williamr@2: williamr@2: composite_key_compare( williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)): williamr@2: super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) williamr@2: {} williamr@2: williamr@2: composite_key_compare(const key_comp_tuple& x):super(x){} williamr@2: williamr@2: const key_comp_tuple& key_comps()const{return *this;} williamr@2: key_comp_tuple& key_comps(){return *this;} williamr@2: williamr@2: template williamr@2: bool operator()( williamr@2: const composite_key_result & x, williamr@2: const composite_key_result & y)const williamr@2: { williamr@2: typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; williamr@2: typedef typename CompositeKey1::value_type value_type1; williamr@2: typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; williamr@2: typedef typename CompositeKey2::value_type value_type2; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value<= williamr@2: tuples::length::value|| williamr@2: tuples::length::value<= williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::compare_ckey_ckey< williamr@2: key_extractor_tuple1,value_type1, williamr@2: key_extractor_tuple2,value_type2, williamr@2: key_comp_tuple williamr@2: >::compare( williamr@2: x.composite_key.key_extractors(),x.value, williamr@2: y.composite_key.key_extractors(),y.value, williamr@2: key_comps()); williamr@2: } williamr@2: williamr@2: #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) williamr@2: template williamr@2: bool operator()( williamr@2: const composite_key_result& x, williamr@2: const Value& y)const williamr@2: { williamr@2: return operator()(x,make_tuple(cref(y))); williamr@2: } williamr@2: #endif williamr@2: williamr@2: template williamr@2: < williamr@2: typename CompositeKey, williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) williamr@2: > williamr@2: bool operator()( williamr@2: const composite_key_result& x, williamr@2: const tuple& y)const williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value<= williamr@2: tuples::length::value|| williamr@2: tuples::length::value<= williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::compare_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,key_comp_tuple williamr@2: >::compare(x.composite_key.key_extractors(),x.value,y,key_comps()); williamr@2: } williamr@2: williamr@2: #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) williamr@2: template williamr@2: bool operator()( williamr@2: const Value& x, williamr@2: const composite_key_result& y)const williamr@2: { williamr@2: return operator()(make_tuple(cref(x)),y); williamr@2: } williamr@2: #endif williamr@2: williamr@2: template williamr@2: < williamr@2: BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), williamr@2: typename CompositeKey williamr@2: > williamr@2: bool operator()( williamr@2: const tuple& x, williamr@2: const composite_key_result& y)const williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value<= williamr@2: tuples::length::value|| williamr@2: tuples::length::value<= williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::compare_ckey_cval< williamr@2: key_extractor_tuple,value_type, williamr@2: key_tuple,key_comp_tuple williamr@2: >::compare(x,y.composite_key.key_extractors(),y.value,key_comps()); williamr@2: } williamr@2: }; williamr@2: williamr@2: /* composite_key_hash */ williamr@2: williamr@2: template williamr@2: < williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash) williamr@2: > williamr@2: struct composite_key_hash: williamr@2: private tuple williamr@2: { williamr@2: private: williamr@2: typedef tuple super; williamr@2: williamr@2: public: williamr@2: typedef super key_hasher_tuple; williamr@2: williamr@2: composite_key_hash( williamr@2: BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)): williamr@2: super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) williamr@2: {} williamr@2: williamr@2: composite_key_hash(const key_hasher_tuple& x):super(x){} williamr@2: williamr@2: const key_hasher_tuple& key_hash_functions()const{return *this;} williamr@2: key_hasher_tuple& key_hash_functions(){return *this;} williamr@2: williamr@2: template williamr@2: std::size_t operator()(const composite_key_result & x)const williamr@2: { williamr@2: typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; williamr@2: typedef typename CompositeKey::value_type value_type; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::hash_ckey< williamr@2: key_extractor_tuple,value_type, williamr@2: key_hasher_tuple williamr@2: >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions()); williamr@2: } williamr@2: williamr@2: template williamr@2: std::size_t operator()( williamr@2: const tuple& x)const williamr@2: { williamr@2: typedef tuple key_tuple; williamr@2: williamr@2: BOOST_STATIC_ASSERT( williamr@2: tuples::length::value== williamr@2: tuples::length::value); williamr@2: williamr@2: return detail::hash_cval< williamr@2: key_tuple,key_hasher_tuple williamr@2: >::hash(x,key_hash_functions()); williamr@2: } williamr@2: }; williamr@2: williamr@2: /* Instantiations of the former functors with "natural" basic components: williamr@2: * composite_key_result_equal_to uses std::equal_to of the values. williamr@2: * composite_key_result_less uses std::less. williamr@2: * composite_key_result_greater uses std::greater. williamr@2: * composite_key_result_hash uses boost::hash. williamr@2: */ williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \ williamr@2: composite_key_equal_to< \ williamr@2: BOOST_MULTI_INDEX_CK_ENUM( \ williamr@2: BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ williamr@2: /* the argument is a PP list */ \ williamr@2: (detail::nth_composite_key_equal_to, \ williamr@2: (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ williamr@2: BOOST_PP_NIL))) \ williamr@2: > williamr@2: williamr@2: template williamr@2: struct composite_key_result_equal_to: williamr@2: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS williamr@2: BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER williamr@2: { williamr@2: private: williamr@2: typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super; williamr@2: williamr@2: public: williamr@2: typedef CompositeKeyResult first_argument_type; williamr@2: typedef first_argument_type second_argument_type; williamr@2: typedef bool result_type; williamr@2: williamr@2: using super::operator(); williamr@2: }; williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \ williamr@2: composite_key_compare< \ williamr@2: BOOST_MULTI_INDEX_CK_ENUM( \ williamr@2: BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ williamr@2: /* the argument is a PP list */ \ williamr@2: (detail::nth_composite_key_less, \ williamr@2: (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ williamr@2: BOOST_PP_NIL))) \ williamr@2: > williamr@2: williamr@2: template williamr@2: struct composite_key_result_less: williamr@2: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS williamr@2: BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER williamr@2: { williamr@2: private: williamr@2: typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super; williamr@2: williamr@2: public: williamr@2: typedef CompositeKeyResult first_argument_type; williamr@2: typedef first_argument_type second_argument_type; williamr@2: typedef bool result_type; williamr@2: williamr@2: using super::operator(); williamr@2: }; williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \ williamr@2: composite_key_compare< \ williamr@2: BOOST_MULTI_INDEX_CK_ENUM( \ williamr@2: BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ williamr@2: /* the argument is a PP list */ \ williamr@2: (detail::nth_composite_key_greater, \ williamr@2: (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ williamr@2: BOOST_PP_NIL))) \ williamr@2: > williamr@2: williamr@2: template williamr@2: struct composite_key_result_greater: williamr@2: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS williamr@2: BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER williamr@2: { williamr@2: private: williamr@2: typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super; williamr@2: williamr@2: public: williamr@2: typedef CompositeKeyResult first_argument_type; williamr@2: typedef first_argument_type second_argument_type; williamr@2: typedef bool result_type; williamr@2: williamr@2: using super::operator(); williamr@2: }; williamr@2: williamr@2: #define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \ williamr@2: composite_key_hash< \ williamr@2: BOOST_MULTI_INDEX_CK_ENUM( \ williamr@2: BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ williamr@2: /* the argument is a PP list */ \ williamr@2: (detail::nth_composite_key_hash, \ williamr@2: (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ williamr@2: BOOST_PP_NIL))) \ williamr@2: > williamr@2: williamr@2: template williamr@2: struct composite_key_result_hash: williamr@2: BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS williamr@2: BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER williamr@2: { williamr@2: private: williamr@2: typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super; williamr@2: williamr@2: public: williamr@2: typedef CompositeKeyResult argument_type; williamr@2: typedef std::size_t result_type; williamr@2: williamr@2: using super::operator(); williamr@2: }; williamr@2: williamr@2: } /* namespace multi_index */ williamr@2: williamr@2: } /* namespace boost */ williamr@2: williamr@2: /* Specializations of std::equal_to, std::less, std::greater and boost::hash williamr@2: * for composite_key_results enabling interoperation with tuples of values. williamr@2: */ williamr@2: williamr@2: #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) williamr@2: namespace std{ williamr@2: williamr@2: template williamr@2: struct equal_to >: williamr@2: boost::multi_index::composite_key_result_equal_to< williamr@2: boost::multi_index::composite_key_result williamr@2: > williamr@2: { williamr@2: }; williamr@2: williamr@2: template williamr@2: struct less >: williamr@2: boost::multi_index::composite_key_result_less< williamr@2: boost::multi_index::composite_key_result williamr@2: > williamr@2: { williamr@2: }; williamr@2: williamr@2: template williamr@2: struct greater >: williamr@2: boost::multi_index::composite_key_result_greater< williamr@2: boost::multi_index::composite_key_result williamr@2: > williamr@2: { williamr@2: }; williamr@2: williamr@2: } /* namespace std */ williamr@2: williamr@2: namespace boost{ williamr@2: williamr@2: template williamr@2: struct hash >: williamr@2: boost::multi_index::composite_key_result_hash< williamr@2: boost::multi_index::composite_key_result williamr@2: > williamr@2: { williamr@2: }; williamr@2: williamr@2: } /* namespace boost */ williamr@2: #else williamr@2: /* Lacking template partial specialization, std::equal_to, std::less and williamr@2: * std::greater will still work for composite_key_results although without williamr@2: * tuple interoperability. To achieve the same graceful degrading with williamr@2: * boost::hash, we define the appropriate hash_value overload. williamr@2: */ williamr@2: williamr@2: namespace boost{ williamr@2: williamr@2: #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) williamr@2: namespace multi_index{ williamr@2: #endif williamr@2: williamr@2: template williamr@2: inline std::size_t hash_value( williamr@2: const boost::multi_index::composite_key_result& x) williamr@2: { williamr@2: boost::multi_index::composite_key_result_hash< williamr@2: boost::multi_index::composite_key_result > h; williamr@2: return h(x); williamr@2: } williamr@2: williamr@2: #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) williamr@2: } /* namespace multi_index */ williamr@2: #endif williamr@2: williamr@2: } /* namespace boost */ williamr@2: #endif williamr@2: williamr@2: #undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER williamr@2: #undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER williamr@2: #undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER williamr@2: #undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER williamr@2: #undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS williamr@2: #undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO williamr@2: #undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR williamr@2: #undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N williamr@2: #undef BOOST_MULTI_INDEX_CK_CTOR_ARG williamr@2: #undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM williamr@2: #undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS williamr@2: #undef BOOST_MULTI_INDEX_CK_ENUM williamr@2: #undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE williamr@2: williamr@2: #endif