1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/multi_index/composite_key.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,1315 @@
1.4 +/* Copyright 2003-2006 Joaquín M López Muñoz.
1.5 + * Distributed under the Boost Software License, Version 1.0.
1.6 + * (See accompanying file LICENSE_1_0.txt or copy at
1.7 + * http://www.boost.org/LICENSE_1_0.txt)
1.8 + *
1.9 + * See http://www.boost.org/libs/multi_index for library home page.
1.10 + */
1.11 +
1.12 +#ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
1.13 +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
1.14 +
1.15 +#if defined(_MSC_VER)&&(_MSC_VER>=1200)
1.16 +#pragma once
1.17 +#endif
1.18 +
1.19 +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
1.20 +#include <boost/multi_index/detail/access_specifier.hpp>
1.21 +#include <boost/multi_index/detail/prevent_eti.hpp>
1.22 +#include <boost/mpl/eval_if.hpp>
1.23 +#include <boost/mpl/identity.hpp>
1.24 +#include <boost/mpl/if.hpp>
1.25 +#include <boost/mpl/or.hpp>
1.26 +#include <boost/mpl/aux_/nttp_decl.hpp>
1.27 +#include <boost/preprocessor/cat.hpp>
1.28 +#include <boost/preprocessor/control/expr_if.hpp>
1.29 +#include <boost/preprocessor/list/at.hpp>
1.30 +#include <boost/preprocessor/repetition/enum.hpp>
1.31 +#include <boost/preprocessor/repetition/enum_params.hpp>
1.32 +#include <boost/static_assert.hpp>
1.33 +#include <boost/tuple/tuple.hpp>
1.34 +#include <boost/type_traits/is_same.hpp>
1.35 +#include <boost/utility/enable_if.hpp>
1.36 +#include <functional>
1.37 +
1.38 +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
1.39 +#include <boost/ref.hpp>
1.40 +#endif
1.41 +
1.42 +#if !defined(BOOST_NO_SFINAE)
1.43 +#include <boost/type_traits/is_convertible.hpp>
1.44 +#endif
1.45 +
1.46 +/* A composite key stores n key extractors and "computes" the
1.47 + * result on a given value as a packed reference to the value and
1.48 + * the composite key itself. Actual invocations to the component
1.49 + * key extractors are lazily performed when executing an operation
1.50 + * on composite_key results (equality, comparison, hashing.)
1.51 + * As the other key extractors in Boost.MultiIndex, composite_key<T,...>
1.52 + * is overloaded to work on chained pointers to T and reference_wrappers
1.53 + * of T.
1.54 + */
1.55 +
1.56 +/* This user_definable macro limits the number of elements of a composite
1.57 + * key; useful for shortening resulting symbol names (MSVC++ 6.0, for
1.58 + * instance has problems coping with very long symbol names.)
1.59 + * NB: This cannot exceed the maximum number of arguments of
1.60 + * boost::tuple. In Boost 1.32, the limit is 10.
1.61 + */
1.62 +
1.63 +#if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE)
1.64 +#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300)
1.65 +#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 5
1.66 +#else
1.67 +#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10
1.68 +#endif
1.69 +#endif
1.70 +
1.71 +/* maximum number of key extractors in a composite key */
1.72 +
1.73 +#if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */
1.74 +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \
1.75 + BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE
1.76 +#else
1.77 +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10
1.78 +#endif
1.79 +
1.80 +/* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
1.81 +
1.82 +#define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \
1.83 + BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data)
1.84 +
1.85 +/* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
1.86 +
1.87 +#define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \
1.88 + BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param)
1.89 +
1.90 +/* if n==0 -> text0
1.91 + * otherwise -> textn=tuples::null_type
1.92 + */
1.93 +
1.94 +#define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \
1.95 + typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type)
1.96 +
1.97 +/* const textn& kn=textn() */
1.98 +
1.99 +#define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \
1.100 + const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)()
1.101 +
1.102 +/* typename list(0)<list(1),n>::type */
1.103 +
1.104 +#define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \
1.105 + BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \
1.106 + BOOST_PP_LIST_AT(list,1),n \
1.107 + >::type
1.108 +
1.109 +namespace boost{
1.110 +
1.111 +template<class T> class reference_wrapper; /* fwd decl. */
1.112 +template<class T> struct hash; /* fwd decl. */
1.113 +
1.114 +namespace multi_index{
1.115 +
1.116 +namespace detail{
1.117 +
1.118 +/* n-th key extractor of a composite key */
1.119 +
1.120 +template<typename CompositeKey,BOOST_MPL_AUX_NTTP_DECL(int, N)>
1.121 +struct nth_key_from_value
1.122 +{
1.123 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.124 + typedef typename prevent_eti<
1.125 + tuples::element<N,key_extractor_tuple>,
1.126 + typename mpl::eval_if_c<
1.127 + N<tuples::length<key_extractor_tuple>::value,
1.128 + tuples::element<N,key_extractor_tuple>,
1.129 + mpl::identity<tuples::null_type>
1.130 + >::type
1.131 + >::type type;
1.132 +};
1.133 +
1.134 +/* nth_composite_key_##name<CompositeKey,N>::type yields
1.135 + * functor<nth_key_from_value<CompositeKey,N> >, or tuples::null_type
1.136 + * if N exceeds the length of the composite key.
1.137 + */
1.138 +
1.139 +#define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \
1.140 +template<typename KeyFromValue> \
1.141 +struct BOOST_PP_CAT(key_,name) \
1.142 +{ \
1.143 + typedef functor<typename KeyFromValue::result_type> type; \
1.144 +}; \
1.145 + \
1.146 +template<> \
1.147 +struct BOOST_PP_CAT(key_,name)<tuples::null_type> \
1.148 +{ \
1.149 + typedef tuples::null_type type; \
1.150 +}; \
1.151 + \
1.152 +template<typename CompositeKey,BOOST_MPL_AUX_NTTP_DECL(int, N)> \
1.153 +struct BOOST_PP_CAT(nth_composite_key_,name) \
1.154 +{ \
1.155 + typedef typename nth_key_from_value<CompositeKey,N>::type key_from_value; \
1.156 + typedef typename BOOST_PP_CAT(key_,name)<key_from_value>::type type; \
1.157 +};
1.158 +
1.159 +/* nth_composite_key_equal_to
1.160 + * nth_composite_key_less
1.161 + * nth_composite_key_greater
1.162 + * nth_composite_key_hash
1.163 + */
1.164 +
1.165 +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to)
1.166 +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less)
1.167 +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater)
1.168 +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash)
1.169 +
1.170 +/* used for defining equality and comparison ops of composite_key_result */
1.171 +
1.172 +#define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text
1.173 +
1.174 +struct generic_operator_equal
1.175 +{
1.176 + template<typename T,typename Q>
1.177 + bool operator()(const T& x,const Q& y)const{return x==y;}
1.178 +};
1.179 +
1.180 +typedef tuple<
1.181 + BOOST_MULTI_INDEX_CK_ENUM(
1.182 + BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
1.183 + detail::generic_operator_equal)> generic_operator_equal_tuple;
1.184 +
1.185 +struct generic_operator_less
1.186 +{
1.187 + template<typename T,typename Q>
1.188 + bool operator()(const T& x,const Q& y)const{return x<y;}
1.189 +};
1.190 +
1.191 +typedef tuple<
1.192 + BOOST_MULTI_INDEX_CK_ENUM(
1.193 + BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
1.194 + detail::generic_operator_less)> generic_operator_less_tuple;
1.195 +
1.196 +/* Metaprogramming machinery for implementing equality, comparison and
1.197 + * hashing operations of composite_key_result.
1.198 + *
1.199 + * equal_* checks for equality between composite_key_results and
1.200 + * between those and tuples, accepting a tuple of basic equality functors.
1.201 + * compare_* does lexicographical comparison.
1.202 + * hash_* computes a combination of elementwise hash values.
1.203 + */
1.204 +
1.205 +template
1.206 +<
1.207 + typename KeyCons1,typename Value1,
1.208 + typename KeyCons2, typename Value2,
1.209 + typename EqualCons
1.210 +>
1.211 +struct equal_ckey_ckey; /* fwd decl. */
1.212 +
1.213 +template
1.214 +<
1.215 + typename KeyCons1,typename Value1,
1.216 + typename KeyCons2, typename Value2,
1.217 + typename EqualCons
1.218 +>
1.219 +struct equal_ckey_ckey_terminal
1.220 +{
1.221 + static bool compare(
1.222 + const KeyCons1&,const Value1&,
1.223 + const KeyCons2&,const Value2&,
1.224 + const EqualCons&)
1.225 + {
1.226 + return true;
1.227 + }
1.228 +};
1.229 +
1.230 +template
1.231 +<
1.232 + typename KeyCons1,typename Value1,
1.233 + typename KeyCons2, typename Value2,
1.234 + typename EqualCons
1.235 +>
1.236 +struct equal_ckey_ckey_normal
1.237 +{
1.238 + static bool compare(
1.239 + const KeyCons1& c0,const Value1& v0,
1.240 + const KeyCons2& c1,const Value2& v1,
1.241 + const EqualCons& eq)
1.242 + {
1.243 + if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false;
1.244 + return equal_ckey_ckey<
1.245 + BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
1.246 + BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
1.247 + BOOST_DEDUCED_TYPENAME EqualCons::tail_type
1.248 + >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail());
1.249 + }
1.250 +};
1.251 +
1.252 +template
1.253 +<
1.254 + typename KeyCons1,typename Value1,
1.255 + typename KeyCons2, typename Value2,
1.256 + typename EqualCons
1.257 +>
1.258 +struct equal_ckey_ckey:
1.259 + mpl::if_<
1.260 + mpl::or_<
1.261 + is_same<KeyCons1,tuples::null_type>,
1.262 + is_same<KeyCons2,tuples::null_type>
1.263 + >,
1.264 + equal_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>,
1.265 + equal_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>
1.266 + >::type
1.267 +{
1.268 +};
1.269 +
1.270 +template
1.271 +<
1.272 + typename KeyCons,typename Value,
1.273 + typename ValCons,typename EqualCons
1.274 +>
1.275 +struct equal_ckey_cval; /* fwd decl. */
1.276 +
1.277 +template
1.278 +<
1.279 + typename KeyCons,typename Value,
1.280 + typename ValCons,typename EqualCons
1.281 +>
1.282 +struct equal_ckey_cval_terminal
1.283 +{
1.284 + static bool compare(
1.285 + const KeyCons&,const Value&,const ValCons&,const EqualCons&)
1.286 + {
1.287 + return true;
1.288 + }
1.289 +
1.290 + static bool compare(
1.291 + const ValCons&,const KeyCons&,const Value&,const EqualCons&)
1.292 + {
1.293 + return true;
1.294 + }
1.295 +};
1.296 +
1.297 +template
1.298 +<
1.299 + typename KeyCons,typename Value,
1.300 + typename ValCons,typename EqualCons
1.301 +>
1.302 +struct equal_ckey_cval_normal
1.303 +{
1.304 + static bool compare(
1.305 + const KeyCons& c,const Value& v,const ValCons& vc,
1.306 + const EqualCons& eq)
1.307 + {
1.308 + if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false;
1.309 + return equal_ckey_cval<
1.310 + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
1.311 + BOOST_DEDUCED_TYPENAME ValCons::tail_type,
1.312 + BOOST_DEDUCED_TYPENAME EqualCons::tail_type
1.313 + >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail());
1.314 + }
1.315 +
1.316 + static bool compare(
1.317 + const ValCons& vc,const KeyCons& c,const Value& v,
1.318 + const EqualCons& eq)
1.319 + {
1.320 + if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false;
1.321 + return equal_ckey_cval<
1.322 + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
1.323 + BOOST_DEDUCED_TYPENAME ValCons::tail_type,
1.324 + BOOST_DEDUCED_TYPENAME EqualCons::tail_type
1.325 + >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail());
1.326 + }
1.327 +};
1.328 +
1.329 +template
1.330 +<
1.331 + typename KeyCons,typename Value,
1.332 + typename ValCons,typename EqualCons
1.333 +>
1.334 +struct equal_ckey_cval:
1.335 + mpl::if_<
1.336 + mpl::or_<
1.337 + is_same<KeyCons,tuples::null_type>,
1.338 + is_same<ValCons,tuples::null_type>
1.339 + >,
1.340 + equal_ckey_cval_terminal<KeyCons,Value,ValCons,EqualCons>,
1.341 + equal_ckey_cval_normal<KeyCons,Value,ValCons,EqualCons>
1.342 + >::type
1.343 +{
1.344 +};
1.345 +
1.346 +template
1.347 +<
1.348 + typename KeyCons1,typename Value1,
1.349 + typename KeyCons2, typename Value2,
1.350 + typename CompareCons
1.351 +>
1.352 +struct compare_ckey_ckey; /* fwd decl. */
1.353 +
1.354 +template
1.355 +<
1.356 + typename KeyCons1,typename Value1,
1.357 + typename KeyCons2, typename Value2,
1.358 + typename CompareCons
1.359 +>
1.360 +struct compare_ckey_ckey_terminal
1.361 +{
1.362 + static bool compare(
1.363 + const KeyCons1&,const Value1&,
1.364 + const KeyCons2&,const Value2&,
1.365 + const CompareCons&)
1.366 + {
1.367 + return false;
1.368 + }
1.369 +};
1.370 +
1.371 +template
1.372 +<
1.373 + typename KeyCons1,typename Value1,
1.374 + typename KeyCons2, typename Value2,
1.375 + typename CompareCons
1.376 +>
1.377 +struct compare_ckey_ckey_normal
1.378 +{
1.379 + static bool compare(
1.380 + const KeyCons1& c0,const Value1& v0,
1.381 + const KeyCons2& c1,const Value2& v1,
1.382 + const CompareCons& comp)
1.383 + {
1.384 + if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true;
1.385 + if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false;
1.386 + return compare_ckey_ckey<
1.387 + BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
1.388 + BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
1.389 + BOOST_DEDUCED_TYPENAME CompareCons::tail_type
1.390 + >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail());
1.391 + }
1.392 +};
1.393 +
1.394 +template
1.395 +<
1.396 + typename KeyCons1,typename Value1,
1.397 + typename KeyCons2, typename Value2,
1.398 + typename CompareCons
1.399 +>
1.400 +struct compare_ckey_ckey:
1.401 + mpl::if_<
1.402 + mpl::or_<
1.403 + is_same<KeyCons1,tuples::null_type>,
1.404 + is_same<KeyCons2,tuples::null_type>
1.405 + >,
1.406 + compare_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>,
1.407 + compare_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>
1.408 + >::type
1.409 +{
1.410 +};
1.411 +
1.412 +template
1.413 +<
1.414 + typename KeyCons,typename Value,
1.415 + typename ValCons,typename CompareCons
1.416 +>
1.417 +struct compare_ckey_cval; /* fwd decl. */
1.418 +
1.419 +template
1.420 +<
1.421 + typename KeyCons,typename Value,
1.422 + typename ValCons,typename CompareCons
1.423 +>
1.424 +struct compare_ckey_cval_terminal
1.425 +{
1.426 + static bool compare(
1.427 + const KeyCons&,const Value&,const ValCons&,const CompareCons&)
1.428 + {
1.429 + return false;
1.430 + }
1.431 +
1.432 + static bool compare(
1.433 + const ValCons&,const KeyCons&,const Value&,const CompareCons&)
1.434 + {
1.435 + return false;
1.436 + }
1.437 +};
1.438 +
1.439 +template
1.440 +<
1.441 + typename KeyCons,typename Value,
1.442 + typename ValCons,typename CompareCons
1.443 +>
1.444 +struct compare_ckey_cval_normal
1.445 +{
1.446 + static bool compare(
1.447 + const KeyCons& c,const Value& v,const ValCons& vc,
1.448 + const CompareCons& comp)
1.449 + {
1.450 + if(comp.get_head()(c.get_head()(v),vc.get_head()))return true;
1.451 + if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false;
1.452 + return compare_ckey_cval<
1.453 + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
1.454 + BOOST_DEDUCED_TYPENAME ValCons::tail_type,
1.455 + BOOST_DEDUCED_TYPENAME CompareCons::tail_type
1.456 + >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail());
1.457 + }
1.458 +
1.459 + static bool compare(
1.460 + const ValCons& vc,const KeyCons& c,const Value& v,
1.461 + const CompareCons& comp)
1.462 + {
1.463 + if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true;
1.464 + if(comp.get_head()(c.get_head()(v),vc.get_head()))return false;
1.465 + return compare_ckey_cval<
1.466 + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
1.467 + BOOST_DEDUCED_TYPENAME ValCons::tail_type,
1.468 + BOOST_DEDUCED_TYPENAME CompareCons::tail_type
1.469 + >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail());
1.470 + }
1.471 +};
1.472 +
1.473 +template
1.474 +<
1.475 + typename KeyCons,typename Value,
1.476 + typename ValCons,typename CompareCons
1.477 +>
1.478 +struct compare_ckey_cval:
1.479 + mpl::if_<
1.480 + mpl::or_<
1.481 + is_same<KeyCons,tuples::null_type>,
1.482 + is_same<ValCons,tuples::null_type>
1.483 + >,
1.484 + compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>,
1.485 + compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons>
1.486 + >::type
1.487 +{
1.488 +};
1.489 +
1.490 +template<typename KeyCons,typename Value,typename HashCons>
1.491 +struct hash_ckey; /* fwd decl. */
1.492 +
1.493 +template<typename KeyCons,typename Value,typename HashCons>
1.494 +struct hash_ckey_terminal
1.495 +{
1.496 + static std::size_t hash(
1.497 + const KeyCons&,const Value&,const HashCons&,std::size_t carry)
1.498 + {
1.499 + return carry;
1.500 + }
1.501 +};
1.502 +
1.503 +template<typename KeyCons,typename Value,typename HashCons>
1.504 +struct hash_ckey_normal
1.505 +{
1.506 + static std::size_t hash(
1.507 + const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0)
1.508 + {
1.509 + /* same hashing formula as boost::hash_combine */
1.510 +
1.511 + carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2);
1.512 + return hash_ckey<
1.513 + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
1.514 + BOOST_DEDUCED_TYPENAME HashCons::tail_type
1.515 + >::hash(c.get_tail(),v,h.get_tail(),carry);
1.516 + }
1.517 +};
1.518 +
1.519 +template<typename KeyCons,typename Value,typename HashCons>
1.520 +struct hash_ckey:
1.521 + mpl::if_<
1.522 + is_same<KeyCons,tuples::null_type>,
1.523 + hash_ckey_terminal<KeyCons,Value,HashCons>,
1.524 + hash_ckey_normal<KeyCons,Value,HashCons>
1.525 + >::type
1.526 +{
1.527 +};
1.528 +
1.529 +template<typename ValCons,typename HashCons>
1.530 +struct hash_cval; /* fwd decl. */
1.531 +
1.532 +template<typename ValCons,typename HashCons>
1.533 +struct hash_cval_terminal
1.534 +{
1.535 + static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry)
1.536 + {
1.537 + return carry;
1.538 + }
1.539 +};
1.540 +
1.541 +template<typename ValCons,typename HashCons>
1.542 +struct hash_cval_normal
1.543 +{
1.544 + static std::size_t hash(
1.545 + const ValCons& vc,const HashCons& h,std::size_t carry=0)
1.546 + {
1.547 + carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2);
1.548 + return hash_cval<
1.549 + BOOST_DEDUCED_TYPENAME ValCons::tail_type,
1.550 + BOOST_DEDUCED_TYPENAME HashCons::tail_type
1.551 + >::hash(vc.get_tail(),h.get_tail(),carry);
1.552 + }
1.553 +};
1.554 +
1.555 +template<typename ValCons,typename HashCons>
1.556 +struct hash_cval:
1.557 + mpl::if_<
1.558 + is_same<ValCons,tuples::null_type>,
1.559 + hash_cval_terminal<ValCons,HashCons>,
1.560 + hash_cval_normal<ValCons,HashCons>
1.561 + >::type
1.562 +{
1.563 +};
1.564 +
1.565 +} /* namespace multi_index::detail */
1.566 +
1.567 +/* composite_key_result */
1.568 +
1.569 +template<typename CompositeKey>
1.570 +struct composite_key_result
1.571 +{
1.572 + typedef CompositeKey composite_key_type;
1.573 + typedef typename composite_key_type::value_type value_type;
1.574 +
1.575 + composite_key_result(
1.576 + const composite_key_type& composite_key_,const value_type& value_):
1.577 + composite_key(composite_key_),value(value_)
1.578 + {}
1.579 +
1.580 + const composite_key_type& composite_key;
1.581 + const value_type& value;
1.582 +};
1.583 +
1.584 +/* composite_key */
1.585 +
1.586 +/* NB. Some overloads of operator() have an extra dummy parameter int=0.
1.587 + * This disambiguator serves several purposes:
1.588 + * - Without it, MSVC++ 6.0 incorrectly regards some overloads as
1.589 + * specializations of a previous member function template.
1.590 + * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
1.591 + * as if they have the same signature.
1.592 + * - If remove_const is broken due to lack of PTS, int=0 avoids the
1.593 + * declaration of memfuns with identical signature.
1.594 + */
1.595 +
1.596 +template<
1.597 + typename Value,
1.598 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
1.599 +>
1.600 +struct composite_key:
1.601 + private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)>
1.602 +{
1.603 +private:
1.604 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super;
1.605 +
1.606 +public:
1.607 + typedef super key_extractor_tuple;
1.608 + typedef Value value_type;
1.609 + typedef composite_key_result<composite_key> result_type;
1.610 +
1.611 + composite_key(
1.612 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)):
1.613 + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
1.614 + {}
1.615 +
1.616 + composite_key(const key_extractor_tuple& x):super(x){}
1.617 +
1.618 + const key_extractor_tuple& key_extractors()const{return *this;}
1.619 + key_extractor_tuple& key_extractors(){return *this;}
1.620 +
1.621 + template<typename ChainedPtr>
1.622 +
1.623 +#if !defined(BOOST_NO_SFINAE)
1.624 + typename disable_if<
1.625 + is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
1.626 +#else
1.627 + result_type
1.628 +#endif
1.629 +
1.630 + operator()(const ChainedPtr& x)const
1.631 + {
1.632 + return operator()(*x);
1.633 + }
1.634 +
1.635 + result_type operator()(const value_type& x)const
1.636 + {
1.637 + return result_type(*this,x);
1.638 + }
1.639 +
1.640 + result_type operator()(const reference_wrapper<const value_type>& x)const
1.641 + {
1.642 + return result_type(*this,x.get());
1.643 + }
1.644 +
1.645 + result_type operator()(const reference_wrapper<value_type>& x,int=0)const
1.646 + {
1.647 + return result_type(*this,x.get());
1.648 + }
1.649 +};
1.650 +
1.651 +/* comparison operators */
1.652 +
1.653 +/* == */
1.654 +
1.655 +template<typename CompositeKey1,typename CompositeKey2>
1.656 +inline bool operator==(
1.657 + const composite_key_result<CompositeKey1>& x,
1.658 + const composite_key_result<CompositeKey2>& y)
1.659 +{
1.660 + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
1.661 + typedef typename CompositeKey1::value_type value_type1;
1.662 + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
1.663 + typedef typename CompositeKey2::value_type value_type2;
1.664 +
1.665 + BOOST_STATIC_ASSERT(
1.666 + tuples::length<key_extractor_tuple1>::value==
1.667 + tuples::length<key_extractor_tuple2>::value);
1.668 +
1.669 + return detail::equal_ckey_ckey<
1.670 + key_extractor_tuple1,value_type1,
1.671 + key_extractor_tuple2,value_type2,
1.672 + detail::generic_operator_equal_tuple
1.673 + >::compare(
1.674 + x.composite_key.key_extractors(),x.value,
1.675 + y.composite_key.key_extractors(),y.value,
1.676 + detail::generic_operator_equal_tuple());
1.677 +}
1.678 +
1.679 +template<
1.680 + typename CompositeKey,
1.681 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
1.682 +>
1.683 +inline bool operator==(
1.684 + const composite_key_result<CompositeKey>& x,
1.685 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
1.686 +{
1.687 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.688 + typedef typename CompositeKey::value_type value_type;
1.689 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.690 +
1.691 + BOOST_STATIC_ASSERT(
1.692 + tuples::length<key_extractor_tuple>::value==
1.693 + tuples::length<key_tuple>::value);
1.694 +
1.695 + return detail::equal_ckey_cval<
1.696 + key_extractor_tuple,value_type,
1.697 + key_tuple,detail::generic_operator_equal_tuple
1.698 + >::compare(
1.699 + x.composite_key.key_extractors(),x.value,
1.700 + y,detail::generic_operator_equal_tuple());
1.701 +}
1.702 +
1.703 +template
1.704 +<
1.705 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1.706 + typename CompositeKey
1.707 +>
1.708 +inline bool operator==(
1.709 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1.710 + const composite_key_result<CompositeKey>& y)
1.711 +{
1.712 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.713 + typedef typename CompositeKey::value_type value_type;
1.714 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.715 +
1.716 + BOOST_STATIC_ASSERT(
1.717 + tuples::length<key_extractor_tuple>::value==
1.718 + tuples::length<key_tuple>::value);
1.719 +
1.720 + return detail::equal_ckey_cval<
1.721 + key_extractor_tuple,value_type,
1.722 + key_tuple,detail::generic_operator_equal_tuple
1.723 + >::compare(
1.724 + x,y.composite_key.key_extractors(),
1.725 + y.value,detail::generic_operator_equal_tuple());
1.726 +}
1.727 +
1.728 +/* < */
1.729 +
1.730 +template<typename CompositeKey1,typename CompositeKey2>
1.731 +inline bool operator<(
1.732 + const composite_key_result<CompositeKey1>& x,
1.733 + const composite_key_result<CompositeKey2>& y)
1.734 +{
1.735 + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
1.736 + typedef typename CompositeKey1::value_type value_type1;
1.737 + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
1.738 + typedef typename CompositeKey2::value_type value_type2;
1.739 +
1.740 + return detail::compare_ckey_ckey<
1.741 + key_extractor_tuple1,value_type1,
1.742 + key_extractor_tuple2,value_type2,
1.743 + detail::generic_operator_less_tuple
1.744 + >::compare(
1.745 + x.composite_key.key_extractors(),x.value,
1.746 + y.composite_key.key_extractors(),y.value,
1.747 + detail::generic_operator_less_tuple());
1.748 +}
1.749 +
1.750 +template
1.751 +<
1.752 + typename CompositeKey,
1.753 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
1.754 +>
1.755 +inline bool operator<(
1.756 + const composite_key_result<CompositeKey>& x,
1.757 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
1.758 +{
1.759 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.760 + typedef typename CompositeKey::value_type value_type;
1.761 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.762 +
1.763 + return detail::compare_ckey_cval<
1.764 + key_extractor_tuple,value_type,
1.765 + key_tuple,detail::generic_operator_less_tuple
1.766 + >::compare(
1.767 + x.composite_key.key_extractors(),x.value,
1.768 + y,detail::generic_operator_less_tuple());
1.769 +}
1.770 +
1.771 +template
1.772 +<
1.773 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1.774 + typename CompositeKey
1.775 +>
1.776 +inline bool operator<(
1.777 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1.778 + const composite_key_result<CompositeKey>& y)
1.779 +{
1.780 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.781 + typedef typename CompositeKey::value_type value_type;
1.782 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.783 +
1.784 + return detail::compare_ckey_cval<
1.785 + key_extractor_tuple,value_type,
1.786 + key_tuple,detail::generic_operator_less_tuple
1.787 + >::compare(
1.788 + x,y.composite_key.key_extractors(),
1.789 + y.value,detail::generic_operator_less_tuple());
1.790 +}
1.791 +
1.792 +/* rest of comparison operators */
1.793 +
1.794 +#define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \
1.795 +template<t1,t2> inline bool operator!=(const a1& x,const a2& y) \
1.796 +{ \
1.797 + return !(x==y); \
1.798 +} \
1.799 + \
1.800 +template<t1,t2> inline bool operator>(const a1& x,const a2& y) \
1.801 +{ \
1.802 + return y<x; \
1.803 +} \
1.804 + \
1.805 +template<t1,t2> inline bool operator>=(const a1& x,const a2& y) \
1.806 +{ \
1.807 + return !(x<y); \
1.808 +} \
1.809 + \
1.810 +template<t1,t2> inline bool operator<=(const a1& x,const a2& y) \
1.811 +{ \
1.812 + return !(y<x); \
1.813 +}
1.814 +
1.815 +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
1.816 + typename CompositeKey1,
1.817 + typename CompositeKey2,
1.818 + composite_key_result<CompositeKey1>,
1.819 + composite_key_result<CompositeKey2>
1.820 +)
1.821 +
1.822 +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
1.823 + typename CompositeKey,
1.824 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1.825 + composite_key_result<CompositeKey>,
1.826 + tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>
1.827 +)
1.828 +
1.829 +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
1.830 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1.831 + typename CompositeKey,
1.832 + tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>,
1.833 + composite_key_result<CompositeKey>
1.834 +)
1.835 +
1.836 +/* composite_key_equal_to */
1.837 +
1.838 +template
1.839 +<
1.840 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred)
1.841 +>
1.842 +struct composite_key_equal_to:
1.843 + private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)>
1.844 +{
1.845 +private:
1.846 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super;
1.847 +
1.848 +public:
1.849 + typedef super key_eq_tuple;
1.850 +
1.851 + composite_key_equal_to(
1.852 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)):
1.853 + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
1.854 + {}
1.855 +
1.856 + composite_key_equal_to(const key_eq_tuple& x):super(x){}
1.857 +
1.858 + const key_eq_tuple& key_eqs()const{return *this;}
1.859 + key_eq_tuple& key_eqs(){return *this;}
1.860 +
1.861 + template<typename CompositeKey1,typename CompositeKey2>
1.862 + bool operator()(
1.863 + const composite_key_result<CompositeKey1> & x,
1.864 + const composite_key_result<CompositeKey2> & y)const
1.865 + {
1.866 + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
1.867 + typedef typename CompositeKey1::value_type value_type1;
1.868 + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
1.869 + typedef typename CompositeKey2::value_type value_type2;
1.870 +
1.871 + BOOST_STATIC_ASSERT(
1.872 + tuples::length<key_extractor_tuple1>::value<=
1.873 + tuples::length<key_eq_tuple>::value&&
1.874 + tuples::length<key_extractor_tuple1>::value==
1.875 + tuples::length<key_extractor_tuple2>::value);
1.876 +
1.877 + return detail::equal_ckey_ckey<
1.878 + key_extractor_tuple1,value_type1,
1.879 + key_extractor_tuple2,value_type2,
1.880 + key_eq_tuple
1.881 + >::compare(
1.882 + x.composite_key.key_extractors(),x.value,
1.883 + y.composite_key.key_extractors(),y.value,
1.884 + key_eqs());
1.885 + }
1.886 +
1.887 + template
1.888 + <
1.889 + typename CompositeKey,
1.890 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
1.891 + >
1.892 + bool operator()(
1.893 + const composite_key_result<CompositeKey>& x,
1.894 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
1.895 + {
1.896 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.897 + typedef typename CompositeKey::value_type value_type;
1.898 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.899 +
1.900 + BOOST_STATIC_ASSERT(
1.901 + tuples::length<key_extractor_tuple>::value<=
1.902 + tuples::length<key_eq_tuple>::value&&
1.903 + tuples::length<key_extractor_tuple>::value==
1.904 + tuples::length<key_tuple>::value);
1.905 +
1.906 + return detail::equal_ckey_cval<
1.907 + key_extractor_tuple,value_type,
1.908 + key_tuple,key_eq_tuple
1.909 + >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs());
1.910 + }
1.911 +
1.912 + template
1.913 + <
1.914 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1.915 + typename CompositeKey
1.916 + >
1.917 + bool operator()(
1.918 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1.919 + const composite_key_result<CompositeKey>& y)const
1.920 + {
1.921 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.922 + typedef typename CompositeKey::value_type value_type;
1.923 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.924 +
1.925 + BOOST_STATIC_ASSERT(
1.926 + tuples::length<key_tuple>::value<=
1.927 + tuples::length<key_eq_tuple>::value&&
1.928 + tuples::length<key_tuple>::value==
1.929 + tuples::length<key_extractor_tuple>::value);
1.930 +
1.931 + return detail::equal_ckey_cval<
1.932 + key_extractor_tuple,value_type,
1.933 + key_tuple,key_eq_tuple
1.934 + >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs());
1.935 + }
1.936 +};
1.937 +
1.938 +/* composite_key_compare */
1.939 +
1.940 +template
1.941 +<
1.942 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare)
1.943 +>
1.944 +struct composite_key_compare:
1.945 + private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)>
1.946 +{
1.947 +private:
1.948 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> super;
1.949 +
1.950 +public:
1.951 + typedef super key_comp_tuple;
1.952 +
1.953 + composite_key_compare(
1.954 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)):
1.955 + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
1.956 + {}
1.957 +
1.958 + composite_key_compare(const key_comp_tuple& x):super(x){}
1.959 +
1.960 + const key_comp_tuple& key_comps()const{return *this;}
1.961 + key_comp_tuple& key_comps(){return *this;}
1.962 +
1.963 + template<typename CompositeKey1,typename CompositeKey2>
1.964 + bool operator()(
1.965 + const composite_key_result<CompositeKey1> & x,
1.966 + const composite_key_result<CompositeKey2> & y)const
1.967 + {
1.968 + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
1.969 + typedef typename CompositeKey1::value_type value_type1;
1.970 + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
1.971 + typedef typename CompositeKey2::value_type value_type2;
1.972 +
1.973 + BOOST_STATIC_ASSERT(
1.974 + tuples::length<key_extractor_tuple1>::value<=
1.975 + tuples::length<key_comp_tuple>::value||
1.976 + tuples::length<key_extractor_tuple2>::value<=
1.977 + tuples::length<key_comp_tuple>::value);
1.978 +
1.979 + return detail::compare_ckey_ckey<
1.980 + key_extractor_tuple1,value_type1,
1.981 + key_extractor_tuple2,value_type2,
1.982 + key_comp_tuple
1.983 + >::compare(
1.984 + x.composite_key.key_extractors(),x.value,
1.985 + y.composite_key.key_extractors(),y.value,
1.986 + key_comps());
1.987 + }
1.988 +
1.989 +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
1.990 + template<typename CompositeKey,typename Value>
1.991 + bool operator()(
1.992 + const composite_key_result<CompositeKey>& x,
1.993 + const Value& y)const
1.994 + {
1.995 + return operator()(x,make_tuple(cref(y)));
1.996 + }
1.997 +#endif
1.998 +
1.999 + template
1.1000 + <
1.1001 + typename CompositeKey,
1.1002 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
1.1003 + >
1.1004 + bool operator()(
1.1005 + const composite_key_result<CompositeKey>& x,
1.1006 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
1.1007 + {
1.1008 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.1009 + typedef typename CompositeKey::value_type value_type;
1.1010 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.1011 +
1.1012 + BOOST_STATIC_ASSERT(
1.1013 + tuples::length<key_extractor_tuple>::value<=
1.1014 + tuples::length<key_comp_tuple>::value||
1.1015 + tuples::length<key_tuple>::value<=
1.1016 + tuples::length<key_comp_tuple>::value);
1.1017 +
1.1018 + return detail::compare_ckey_cval<
1.1019 + key_extractor_tuple,value_type,
1.1020 + key_tuple,key_comp_tuple
1.1021 + >::compare(x.composite_key.key_extractors(),x.value,y,key_comps());
1.1022 + }
1.1023 +
1.1024 +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
1.1025 + template<typename Value,typename CompositeKey>
1.1026 + bool operator()(
1.1027 + const Value& x,
1.1028 + const composite_key_result<CompositeKey>& y)const
1.1029 + {
1.1030 + return operator()(make_tuple(cref(x)),y);
1.1031 + }
1.1032 +#endif
1.1033 +
1.1034 + template
1.1035 + <
1.1036 + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
1.1037 + typename CompositeKey
1.1038 + >
1.1039 + bool operator()(
1.1040 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
1.1041 + const composite_key_result<CompositeKey>& y)const
1.1042 + {
1.1043 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.1044 + typedef typename CompositeKey::value_type value_type;
1.1045 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.1046 +
1.1047 + BOOST_STATIC_ASSERT(
1.1048 + tuples::length<key_tuple>::value<=
1.1049 + tuples::length<key_comp_tuple>::value||
1.1050 + tuples::length<key_extractor_tuple>::value<=
1.1051 + tuples::length<key_comp_tuple>::value);
1.1052 +
1.1053 + return detail::compare_ckey_cval<
1.1054 + key_extractor_tuple,value_type,
1.1055 + key_tuple,key_comp_tuple
1.1056 + >::compare(x,y.composite_key.key_extractors(),y.value,key_comps());
1.1057 + }
1.1058 +};
1.1059 +
1.1060 +/* composite_key_hash */
1.1061 +
1.1062 +template
1.1063 +<
1.1064 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash)
1.1065 +>
1.1066 +struct composite_key_hash:
1.1067 + private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)>
1.1068 +{
1.1069 +private:
1.1070 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> super;
1.1071 +
1.1072 +public:
1.1073 + typedef super key_hasher_tuple;
1.1074 +
1.1075 + composite_key_hash(
1.1076 + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)):
1.1077 + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
1.1078 + {}
1.1079 +
1.1080 + composite_key_hash(const key_hasher_tuple& x):super(x){}
1.1081 +
1.1082 + const key_hasher_tuple& key_hash_functions()const{return *this;}
1.1083 + key_hasher_tuple& key_hash_functions(){return *this;}
1.1084 +
1.1085 + template<typename CompositeKey>
1.1086 + std::size_t operator()(const composite_key_result<CompositeKey> & x)const
1.1087 + {
1.1088 + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
1.1089 + typedef typename CompositeKey::value_type value_type;
1.1090 +
1.1091 + BOOST_STATIC_ASSERT(
1.1092 + tuples::length<key_extractor_tuple>::value==
1.1093 + tuples::length<key_hasher_tuple>::value);
1.1094 +
1.1095 + return detail::hash_ckey<
1.1096 + key_extractor_tuple,value_type,
1.1097 + key_hasher_tuple
1.1098 + >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions());
1.1099 + }
1.1100 +
1.1101 + template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)>
1.1102 + std::size_t operator()(
1.1103 + const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const
1.1104 + {
1.1105 + typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
1.1106 +
1.1107 + BOOST_STATIC_ASSERT(
1.1108 + tuples::length<key_tuple>::value==
1.1109 + tuples::length<key_hasher_tuple>::value);
1.1110 +
1.1111 + return detail::hash_cval<
1.1112 + key_tuple,key_hasher_tuple
1.1113 + >::hash(x,key_hash_functions());
1.1114 + }
1.1115 +};
1.1116 +
1.1117 +/* Instantiations of the former functors with "natural" basic components:
1.1118 + * composite_key_result_equal_to uses std::equal_to of the values.
1.1119 + * composite_key_result_less uses std::less.
1.1120 + * composite_key_result_greater uses std::greater.
1.1121 + * composite_key_result_hash uses boost::hash.
1.1122 + */
1.1123 +
1.1124 +#define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \
1.1125 +composite_key_equal_to< \
1.1126 + BOOST_MULTI_INDEX_CK_ENUM( \
1.1127 + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1.1128 + /* the argument is a PP list */ \
1.1129 + (detail::nth_composite_key_equal_to, \
1.1130 + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1.1131 + BOOST_PP_NIL))) \
1.1132 + >
1.1133 +
1.1134 +template<typename CompositeKeyResult>
1.1135 +struct composite_key_result_equal_to:
1.1136 +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1.1137 +BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
1.1138 +{
1.1139 +private:
1.1140 + typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super;
1.1141 +
1.1142 +public:
1.1143 + typedef CompositeKeyResult first_argument_type;
1.1144 + typedef first_argument_type second_argument_type;
1.1145 + typedef bool result_type;
1.1146 +
1.1147 + using super::operator();
1.1148 +};
1.1149 +
1.1150 +#define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \
1.1151 +composite_key_compare< \
1.1152 + BOOST_MULTI_INDEX_CK_ENUM( \
1.1153 + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1.1154 + /* the argument is a PP list */ \
1.1155 + (detail::nth_composite_key_less, \
1.1156 + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1.1157 + BOOST_PP_NIL))) \
1.1158 + >
1.1159 +
1.1160 +template<typename CompositeKeyResult>
1.1161 +struct composite_key_result_less:
1.1162 +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1.1163 +BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
1.1164 +{
1.1165 +private:
1.1166 + typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super;
1.1167 +
1.1168 +public:
1.1169 + typedef CompositeKeyResult first_argument_type;
1.1170 + typedef first_argument_type second_argument_type;
1.1171 + typedef bool result_type;
1.1172 +
1.1173 + using super::operator();
1.1174 +};
1.1175 +
1.1176 +#define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \
1.1177 +composite_key_compare< \
1.1178 + BOOST_MULTI_INDEX_CK_ENUM( \
1.1179 + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1.1180 + /* the argument is a PP list */ \
1.1181 + (detail::nth_composite_key_greater, \
1.1182 + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1.1183 + BOOST_PP_NIL))) \
1.1184 + >
1.1185 +
1.1186 +template<typename CompositeKeyResult>
1.1187 +struct composite_key_result_greater:
1.1188 +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1.1189 +BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
1.1190 +{
1.1191 +private:
1.1192 + typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super;
1.1193 +
1.1194 +public:
1.1195 + typedef CompositeKeyResult first_argument_type;
1.1196 + typedef first_argument_type second_argument_type;
1.1197 + typedef bool result_type;
1.1198 +
1.1199 + using super::operator();
1.1200 +};
1.1201 +
1.1202 +#define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \
1.1203 +composite_key_hash< \
1.1204 + BOOST_MULTI_INDEX_CK_ENUM( \
1.1205 + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
1.1206 + /* the argument is a PP list */ \
1.1207 + (detail::nth_composite_key_hash, \
1.1208 + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
1.1209 + BOOST_PP_NIL))) \
1.1210 + >
1.1211 +
1.1212 +template<typename CompositeKeyResult>
1.1213 +struct composite_key_result_hash:
1.1214 +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
1.1215 +BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
1.1216 +{
1.1217 +private:
1.1218 + typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super;
1.1219 +
1.1220 +public:
1.1221 + typedef CompositeKeyResult argument_type;
1.1222 + typedef std::size_t result_type;
1.1223 +
1.1224 + using super::operator();
1.1225 +};
1.1226 +
1.1227 +} /* namespace multi_index */
1.1228 +
1.1229 +} /* namespace boost */
1.1230 +
1.1231 +/* Specializations of std::equal_to, std::less, std::greater and boost::hash
1.1232 + * for composite_key_results enabling interoperation with tuples of values.
1.1233 + */
1.1234 +
1.1235 +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
1.1236 +namespace std{
1.1237 +
1.1238 +template<typename CompositeKey>
1.1239 +struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >:
1.1240 + boost::multi_index::composite_key_result_equal_to<
1.1241 + boost::multi_index::composite_key_result<CompositeKey>
1.1242 + >
1.1243 +{
1.1244 +};
1.1245 +
1.1246 +template<typename CompositeKey>
1.1247 +struct less<boost::multi_index::composite_key_result<CompositeKey> >:
1.1248 + boost::multi_index::composite_key_result_less<
1.1249 + boost::multi_index::composite_key_result<CompositeKey>
1.1250 + >
1.1251 +{
1.1252 +};
1.1253 +
1.1254 +template<typename CompositeKey>
1.1255 +struct greater<boost::multi_index::composite_key_result<CompositeKey> >:
1.1256 + boost::multi_index::composite_key_result_greater<
1.1257 + boost::multi_index::composite_key_result<CompositeKey>
1.1258 + >
1.1259 +{
1.1260 +};
1.1261 +
1.1262 +} /* namespace std */
1.1263 +
1.1264 +namespace boost{
1.1265 +
1.1266 +template<typename CompositeKey>
1.1267 +struct hash<boost::multi_index::composite_key_result<CompositeKey> >:
1.1268 + boost::multi_index::composite_key_result_hash<
1.1269 + boost::multi_index::composite_key_result<CompositeKey>
1.1270 + >
1.1271 +{
1.1272 +};
1.1273 +
1.1274 +} /* namespace boost */
1.1275 +#else
1.1276 +/* Lacking template partial specialization, std::equal_to, std::less and
1.1277 + * std::greater will still work for composite_key_results although without
1.1278 + * tuple interoperability. To achieve the same graceful degrading with
1.1279 + * boost::hash, we define the appropriate hash_value overload.
1.1280 + */
1.1281 +
1.1282 +namespace boost{
1.1283 +
1.1284 +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1.1285 +namespace multi_index{
1.1286 +#endif
1.1287 +
1.1288 +template<typename CompositeKey>
1.1289 +inline std::size_t hash_value(
1.1290 + const boost::multi_index::composite_key_result<CompositeKey>& x)
1.1291 +{
1.1292 + boost::multi_index::composite_key_result_hash<
1.1293 + boost::multi_index::composite_key_result<CompositeKey> > h;
1.1294 + return h(x);
1.1295 +}
1.1296 +
1.1297 +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1.1298 +} /* namespace multi_index */
1.1299 +#endif
1.1300 +
1.1301 +} /* namespace boost */
1.1302 +#endif
1.1303 +
1.1304 +#undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
1.1305 +#undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
1.1306 +#undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
1.1307 +#undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
1.1308 +#undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS
1.1309 +#undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO
1.1310 +#undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR
1.1311 +#undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N
1.1312 +#undef BOOST_MULTI_INDEX_CK_CTOR_ARG
1.1313 +#undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM
1.1314 +#undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS
1.1315 +#undef BOOST_MULTI_INDEX_CK_ENUM
1.1316 +#undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE
1.1317 +
1.1318 +#endif