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