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