epoc32/include/stdapis/boost/multi_index/composite_key.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
williamr@2
     1
/* Copyright 2003-2006 Joaquín M López Muñoz.
williamr@2
     2
 * Distributed under the Boost Software License, Version 1.0.
williamr@2
     3
 * (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     4
 * http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     5
 *
williamr@2
     6
 * See http://www.boost.org/libs/multi_index for library home page.
williamr@2
     7
 */
williamr@2
     8
williamr@2
     9
#ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
williamr@2
    10
#define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
williamr@2
    11
williamr@2
    12
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
williamr@2
    13
#pragma once
williamr@2
    14
#endif
williamr@2
    15
williamr@2
    16
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
williamr@2
    17
#include <boost/multi_index/detail/access_specifier.hpp>
williamr@2
    18
#include <boost/multi_index/detail/prevent_eti.hpp>
williamr@2
    19
#include <boost/mpl/eval_if.hpp>
williamr@2
    20
#include <boost/mpl/identity.hpp>
williamr@2
    21
#include <boost/mpl/if.hpp>
williamr@2
    22
#include <boost/mpl/or.hpp>
williamr@2
    23
#include <boost/mpl/aux_/nttp_decl.hpp>
williamr@2
    24
#include <boost/preprocessor/cat.hpp>
williamr@2
    25
#include <boost/preprocessor/control/expr_if.hpp>
williamr@2
    26
#include <boost/preprocessor/list/at.hpp>
williamr@2
    27
#include <boost/preprocessor/repetition/enum.hpp>
williamr@2
    28
#include <boost/preprocessor/repetition/enum_params.hpp> 
williamr@2
    29
#include <boost/static_assert.hpp>
williamr@2
    30
#include <boost/tuple/tuple.hpp>
williamr@2
    31
#include <boost/type_traits/is_same.hpp>
williamr@2
    32
#include <boost/utility/enable_if.hpp>
williamr@2
    33
#include <functional>
williamr@2
    34
williamr@2
    35
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
williamr@2
    36
#include <boost/ref.hpp>
williamr@2
    37
#endif
williamr@2
    38
williamr@2
    39
#if !defined(BOOST_NO_SFINAE)
williamr@2
    40
#include <boost/type_traits/is_convertible.hpp>
williamr@2
    41
#endif
williamr@2
    42
williamr@2
    43
/* A composite key stores n key extractors and "computes" the
williamr@2
    44
 * result on a given value as a packed reference to the value and
williamr@2
    45
 * the composite key itself. Actual invocations to the component
williamr@2
    46
 * key extractors are lazily performed when executing an operation
williamr@2
    47
 * on composite_key results (equality, comparison, hashing.)
williamr@2
    48
 * As the other key extractors in Boost.MultiIndex, composite_key<T,...>
williamr@2
    49
 * is  overloaded to work on chained pointers to T and reference_wrappers
williamr@2
    50
 * of T.
williamr@2
    51
 */
williamr@2
    52
williamr@2
    53
/* This user_definable macro limits the number of elements of a composite
williamr@2
    54
 * key; useful for shortening resulting symbol names (MSVC++ 6.0, for
williamr@2
    55
 * instance has problems coping with very long symbol names.)
williamr@2
    56
 * NB: This cannot exceed the maximum number of arguments of
williamr@2
    57
 * boost::tuple. In Boost 1.32, the limit is 10.
williamr@2
    58
 */
williamr@2
    59
williamr@2
    60
#if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE)
williamr@2
    61
#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300)
williamr@2
    62
#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 5
williamr@2
    63
#else
williamr@2
    64
#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10
williamr@2
    65
#endif
williamr@2
    66
#endif
williamr@2
    67
williamr@2
    68
/* maximum number of key extractors in a composite key */
williamr@2
    69
williamr@2
    70
#if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */
williamr@2
    71
#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \
williamr@2
    72
  BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE
williamr@2
    73
#else
williamr@2
    74
#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10
williamr@2
    75
#endif
williamr@2
    76
williamr@2
    77
/* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
williamr@2
    78
williamr@2
    79
#define BOOST_MULTI_INDEX_CK_ENUM(macro,data)                                \
williamr@2
    80
  BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data)
williamr@2
    81
williamr@2
    82
/* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
williamr@2
    83
williamr@2
    84
#define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param)                              \
williamr@2
    85
  BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param)
williamr@2
    86
williamr@2
    87
/* if n==0 ->   text0
williamr@2
    88
 * otherwise -> textn=tuples::null_type
williamr@2
    89
 */
williamr@2
    90
williamr@2
    91
#define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text)                         \
williamr@2
    92
  typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type)
williamr@2
    93
williamr@2
    94
/* const textn& kn=textn() */
williamr@2
    95
williamr@2
    96
#define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text)                              \
williamr@2
    97
  const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)()
williamr@2
    98
williamr@2
    99
/* typename list(0)<list(1),n>::type */
williamr@2
   100
williamr@2
   101
#define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list)                  \
williamr@2
   102
  BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)<                           \
williamr@2
   103
    BOOST_PP_LIST_AT(list,1),n                                               \
williamr@2
   104
  >::type
williamr@2
   105
williamr@2
   106
namespace boost{
williamr@2
   107
williamr@2
   108
template<class T> class reference_wrapper; /* fwd decl. */
williamr@2
   109
template<class T> struct hash; /* fwd decl. */
williamr@2
   110
williamr@2
   111
namespace multi_index{
williamr@2
   112
williamr@2
   113
namespace detail{
williamr@2
   114
williamr@2
   115
/* n-th key extractor of a composite key */
williamr@2
   116
williamr@2
   117
template<typename CompositeKey,BOOST_MPL_AUX_NTTP_DECL(int, N)>
williamr@2
   118
struct nth_key_from_value
williamr@2
   119
{
williamr@2
   120
  typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
williamr@2
   121
  typedef typename prevent_eti<
williamr@2
   122
    tuples::element<N,key_extractor_tuple>,
williamr@2
   123
    typename mpl::eval_if_c<
williamr@2
   124
      N<tuples::length<key_extractor_tuple>::value,
williamr@2
   125
      tuples::element<N,key_extractor_tuple>,
williamr@2
   126
      mpl::identity<tuples::null_type>
williamr@2
   127
    >::type
williamr@2
   128
  >::type                                            type;
williamr@2
   129
};
williamr@2
   130
williamr@2
   131
/* nth_composite_key_##name<CompositeKey,N>::type yields
williamr@2
   132
 * functor<nth_key_from_value<CompositeKey,N> >, or tuples::null_type
williamr@2
   133
 * if N exceeds the length of the composite key.
williamr@2
   134
 */
williamr@2
   135
williamr@2
   136
#define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor)         \
williamr@2
   137
template<typename KeyFromValue>                                              \
williamr@2
   138
struct BOOST_PP_CAT(key_,name)                                               \
williamr@2
   139
{                                                                            \
williamr@2
   140
  typedef functor<typename KeyFromValue::result_type> type;                  \
williamr@2
   141
};                                                                           \
williamr@2
   142
                                                                             \
williamr@2
   143
template<>                                                                   \
williamr@2
   144
struct BOOST_PP_CAT(key_,name)<tuples::null_type>                            \
williamr@2
   145
{                                                                            \
williamr@2
   146
  typedef tuples::null_type type;                                            \
williamr@2
   147
};                                                                           \
williamr@2
   148
                                                                             \
williamr@2
   149
template<typename CompositeKey,BOOST_MPL_AUX_NTTP_DECL(int, N)>              \
williamr@2
   150
struct BOOST_PP_CAT(nth_composite_key_,name)                                 \
williamr@2
   151
{                                                                            \
williamr@2
   152
  typedef typename nth_key_from_value<CompositeKey,N>::type key_from_value;  \
williamr@2
   153
  typedef typename BOOST_PP_CAT(key_,name)<key_from_value>::type type;       \
williamr@2
   154
};
williamr@2
   155
williamr@2
   156
/* nth_composite_key_equal_to
williamr@2
   157
 * nth_composite_key_less
williamr@2
   158
 * nth_composite_key_greater
williamr@2
   159
 * nth_composite_key_hash
williamr@2
   160
 */
williamr@2
   161
williamr@2
   162
BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to)
williamr@2
   163
BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less)
williamr@2
   164
BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater)
williamr@2
   165
BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash)
williamr@2
   166
williamr@2
   167
/* used for defining equality and comparison ops of composite_key_result */
williamr@2
   168
williamr@2
   169
#define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text
williamr@2
   170
williamr@2
   171
struct generic_operator_equal
williamr@2
   172
{
williamr@2
   173
  template<typename T,typename Q>
williamr@2
   174
  bool operator()(const T& x,const Q& y)const{return x==y;}
williamr@2
   175
};
williamr@2
   176
williamr@2
   177
typedef tuple<
williamr@2
   178
  BOOST_MULTI_INDEX_CK_ENUM(
williamr@2
   179
    BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
williamr@2
   180
    detail::generic_operator_equal)>          generic_operator_equal_tuple;
williamr@2
   181
williamr@2
   182
struct generic_operator_less
williamr@2
   183
{
williamr@2
   184
  template<typename T,typename Q>
williamr@2
   185
  bool operator()(const T& x,const Q& y)const{return x<y;}
williamr@2
   186
};
williamr@2
   187
williamr@2
   188
typedef tuple<
williamr@2
   189
  BOOST_MULTI_INDEX_CK_ENUM(
williamr@2
   190
    BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
williamr@2
   191
    detail::generic_operator_less)>           generic_operator_less_tuple;
williamr@2
   192
williamr@2
   193
/* Metaprogramming machinery for implementing equality, comparison and
williamr@2
   194
 * hashing operations of composite_key_result.
williamr@2
   195
 *
williamr@2
   196
 * equal_* checks for equality between composite_key_results and
williamr@2
   197
 * between those and tuples, accepting a tuple of basic equality functors.
williamr@2
   198
 * compare_* does lexicographical comparison.
williamr@2
   199
 * hash_* computes a combination of elementwise hash values.
williamr@2
   200
 */
williamr@2
   201
williamr@2
   202
template
williamr@2
   203
<
williamr@2
   204
  typename KeyCons1,typename Value1,
williamr@2
   205
  typename KeyCons2, typename Value2,
williamr@2
   206
  typename EqualCons
williamr@2
   207
>
williamr@2
   208
struct equal_ckey_ckey; /* fwd decl. */
williamr@2
   209
williamr@2
   210
template
williamr@2
   211
<
williamr@2
   212
  typename KeyCons1,typename Value1,
williamr@2
   213
  typename KeyCons2, typename Value2,
williamr@2
   214
  typename EqualCons
williamr@2
   215
>
williamr@2
   216
struct equal_ckey_ckey_terminal
williamr@2
   217
{
williamr@2
   218
  static bool compare(
williamr@2
   219
    const KeyCons1&,const Value1&,
williamr@2
   220
    const KeyCons2&,const Value2&,
williamr@2
   221
    const EqualCons&)
williamr@2
   222
  {
williamr@2
   223
    return true;
williamr@2
   224
  }
williamr@2
   225
};
williamr@2
   226
williamr@2
   227
template
williamr@2
   228
<
williamr@2
   229
  typename KeyCons1,typename Value1,
williamr@2
   230
  typename KeyCons2, typename Value2,
williamr@2
   231
  typename EqualCons
williamr@2
   232
>
williamr@2
   233
struct equal_ckey_ckey_normal
williamr@2
   234
{
williamr@2
   235
  static bool compare(
williamr@2
   236
    const KeyCons1& c0,const Value1& v0,
williamr@2
   237
    const KeyCons2& c1,const Value2& v1,
williamr@2
   238
    const EqualCons& eq)
williamr@2
   239
  {
williamr@2
   240
    if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false;
williamr@2
   241
    return equal_ckey_ckey<
williamr@2
   242
      BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
williamr@2
   243
      BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
williamr@2
   244
      BOOST_DEDUCED_TYPENAME EqualCons::tail_type
williamr@2
   245
    >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail());
williamr@2
   246
  }
williamr@2
   247
};
williamr@2
   248
williamr@2
   249
template
williamr@2
   250
<
williamr@2
   251
  typename KeyCons1,typename Value1,
williamr@2
   252
  typename KeyCons2, typename Value2,
williamr@2
   253
  typename EqualCons
williamr@2
   254
>
williamr@2
   255
struct equal_ckey_ckey:
williamr@2
   256
  mpl::if_<
williamr@2
   257
    mpl::or_<
williamr@2
   258
      is_same<KeyCons1,tuples::null_type>,
williamr@2
   259
      is_same<KeyCons2,tuples::null_type>
williamr@2
   260
    >,
williamr@2
   261
    equal_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>,
williamr@2
   262
    equal_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>
williamr@2
   263
  >::type
williamr@2
   264
{
williamr@2
   265
};
williamr@2
   266
williamr@2
   267
template
williamr@2
   268
<
williamr@2
   269
  typename KeyCons,typename Value,
williamr@2
   270
  typename ValCons,typename EqualCons
williamr@2
   271
>
williamr@2
   272
struct equal_ckey_cval; /* fwd decl. */
williamr@2
   273
williamr@2
   274
template
williamr@2
   275
<
williamr@2
   276
  typename KeyCons,typename Value,
williamr@2
   277
  typename ValCons,typename EqualCons
williamr@2
   278
>
williamr@2
   279
struct equal_ckey_cval_terminal
williamr@2
   280
{
williamr@2
   281
  static bool compare(
williamr@2
   282
    const KeyCons&,const Value&,const ValCons&,const EqualCons&)
williamr@2
   283
  {
williamr@2
   284
    return true;
williamr@2
   285
  }
williamr@2
   286
williamr@2
   287
  static bool compare(
williamr@2
   288
    const ValCons&,const KeyCons&,const Value&,const EqualCons&)
williamr@2
   289
  {
williamr@2
   290
    return true;
williamr@2
   291
  }
williamr@2
   292
};
williamr@2
   293
williamr@2
   294
template
williamr@2
   295
<
williamr@2
   296
  typename KeyCons,typename Value,
williamr@2
   297
  typename ValCons,typename EqualCons
williamr@2
   298
>
williamr@2
   299
struct equal_ckey_cval_normal
williamr@2
   300
{
williamr@2
   301
  static bool compare(
williamr@2
   302
    const KeyCons& c,const Value& v,const ValCons& vc,
williamr@2
   303
    const EqualCons& eq)
williamr@2
   304
  {
williamr@2
   305
    if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false;
williamr@2
   306
    return equal_ckey_cval<
williamr@2
   307
      BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
williamr@2
   308
      BOOST_DEDUCED_TYPENAME ValCons::tail_type,
williamr@2
   309
      BOOST_DEDUCED_TYPENAME EqualCons::tail_type
williamr@2
   310
    >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail());
williamr@2
   311
  }
williamr@2
   312
williamr@2
   313
  static bool compare(
williamr@2
   314
    const ValCons& vc,const KeyCons& c,const Value& v,
williamr@2
   315
    const EqualCons& eq)
williamr@2
   316
  {
williamr@2
   317
    if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false;
williamr@2
   318
    return equal_ckey_cval<
williamr@2
   319
      BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
williamr@2
   320
      BOOST_DEDUCED_TYPENAME ValCons::tail_type,
williamr@2
   321
      BOOST_DEDUCED_TYPENAME EqualCons::tail_type
williamr@2
   322
    >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail());
williamr@2
   323
  }
williamr@2
   324
};
williamr@2
   325
williamr@2
   326
template
williamr@2
   327
<
williamr@2
   328
  typename KeyCons,typename Value,
williamr@2
   329
  typename ValCons,typename EqualCons
williamr@2
   330
>
williamr@2
   331
struct equal_ckey_cval:
williamr@2
   332
  mpl::if_<
williamr@2
   333
    mpl::or_<
williamr@2
   334
      is_same<KeyCons,tuples::null_type>,
williamr@2
   335
      is_same<ValCons,tuples::null_type>
williamr@2
   336
    >,
williamr@2
   337
    equal_ckey_cval_terminal<KeyCons,Value,ValCons,EqualCons>,
williamr@2
   338
    equal_ckey_cval_normal<KeyCons,Value,ValCons,EqualCons>
williamr@2
   339
  >::type
williamr@2
   340
{
williamr@2
   341
};
williamr@2
   342
williamr@2
   343
template
williamr@2
   344
<
williamr@2
   345
  typename KeyCons1,typename Value1,
williamr@2
   346
  typename KeyCons2, typename Value2,
williamr@2
   347
  typename CompareCons
williamr@2
   348
>
williamr@2
   349
struct compare_ckey_ckey; /* fwd decl. */
williamr@2
   350
williamr@2
   351
template
williamr@2
   352
<
williamr@2
   353
  typename KeyCons1,typename Value1,
williamr@2
   354
  typename KeyCons2, typename Value2,
williamr@2
   355
  typename CompareCons
williamr@2
   356
>
williamr@2
   357
struct compare_ckey_ckey_terminal
williamr@2
   358
{
williamr@2
   359
  static bool compare(
williamr@2
   360
    const KeyCons1&,const Value1&,
williamr@2
   361
    const KeyCons2&,const Value2&,
williamr@2
   362
    const CompareCons&)
williamr@2
   363
  {
williamr@2
   364
    return false;
williamr@2
   365
  }
williamr@2
   366
};
williamr@2
   367
williamr@2
   368
template
williamr@2
   369
<
williamr@2
   370
  typename KeyCons1,typename Value1,
williamr@2
   371
  typename KeyCons2, typename Value2,
williamr@2
   372
  typename CompareCons
williamr@2
   373
>
williamr@2
   374
struct compare_ckey_ckey_normal
williamr@2
   375
{
williamr@2
   376
  static bool compare(
williamr@2
   377
    const KeyCons1& c0,const Value1& v0,
williamr@2
   378
    const KeyCons2& c1,const Value2& v1,
williamr@2
   379
    const CompareCons& comp)
williamr@2
   380
  {
williamr@2
   381
    if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true;
williamr@2
   382
    if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false;
williamr@2
   383
    return compare_ckey_ckey<
williamr@2
   384
      BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
williamr@2
   385
      BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
williamr@2
   386
      BOOST_DEDUCED_TYPENAME CompareCons::tail_type
williamr@2
   387
    >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail());
williamr@2
   388
  }
williamr@2
   389
};
williamr@2
   390
williamr@2
   391
template
williamr@2
   392
<
williamr@2
   393
  typename KeyCons1,typename Value1,
williamr@2
   394
  typename KeyCons2, typename Value2,
williamr@2
   395
  typename CompareCons
williamr@2
   396
>
williamr@2
   397
struct compare_ckey_ckey:
williamr@2
   398
  mpl::if_<
williamr@2
   399
    mpl::or_<
williamr@2
   400
      is_same<KeyCons1,tuples::null_type>,
williamr@2
   401
      is_same<KeyCons2,tuples::null_type>
williamr@2
   402
    >,
williamr@2
   403
    compare_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>,
williamr@2
   404
    compare_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>
williamr@2
   405
  >::type
williamr@2
   406
{
williamr@2
   407
};
williamr@2
   408
williamr@2
   409
template
williamr@2
   410
<
williamr@2
   411
  typename KeyCons,typename Value,
williamr@2
   412
  typename ValCons,typename CompareCons
williamr@2
   413
>
williamr@2
   414
struct compare_ckey_cval; /* fwd decl. */
williamr@2
   415
williamr@2
   416
template
williamr@2
   417
<
williamr@2
   418
  typename KeyCons,typename Value,
williamr@2
   419
  typename ValCons,typename CompareCons
williamr@2
   420
>
williamr@2
   421
struct compare_ckey_cval_terminal
williamr@2
   422
{
williamr@2
   423
  static bool compare(
williamr@2
   424
    const KeyCons&,const Value&,const ValCons&,const CompareCons&)
williamr@2
   425
  {
williamr@2
   426
    return false;
williamr@2
   427
  }
williamr@2
   428
williamr@2
   429
  static bool compare(
williamr@2
   430
    const ValCons&,const KeyCons&,const Value&,const CompareCons&)
williamr@2
   431
  {
williamr@2
   432
    return false;
williamr@2
   433
  }
williamr@2
   434
};
williamr@2
   435
williamr@2
   436
template
williamr@2
   437
<
williamr@2
   438
  typename KeyCons,typename Value,
williamr@2
   439
  typename ValCons,typename CompareCons
williamr@2
   440
>
williamr@2
   441
struct compare_ckey_cval_normal
williamr@2
   442
{
williamr@2
   443
  static bool compare(
williamr@2
   444
    const KeyCons& c,const Value& v,const ValCons& vc,
williamr@2
   445
    const CompareCons& comp)
williamr@2
   446
  {
williamr@2
   447
    if(comp.get_head()(c.get_head()(v),vc.get_head()))return true;
williamr@2
   448
    if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false;
williamr@2
   449
    return compare_ckey_cval<
williamr@2
   450
      BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
williamr@2
   451
      BOOST_DEDUCED_TYPENAME ValCons::tail_type,
williamr@2
   452
      BOOST_DEDUCED_TYPENAME CompareCons::tail_type
williamr@2
   453
    >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail());
williamr@2
   454
  }
williamr@2
   455
williamr@2
   456
  static bool compare(
williamr@2
   457
    const ValCons& vc,const KeyCons& c,const Value& v,
williamr@2
   458
    const CompareCons& comp)
williamr@2
   459
  {
williamr@2
   460
    if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true;
williamr@2
   461
    if(comp.get_head()(c.get_head()(v),vc.get_head()))return false;
williamr@2
   462
    return compare_ckey_cval<
williamr@2
   463
      BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
williamr@2
   464
      BOOST_DEDUCED_TYPENAME ValCons::tail_type,
williamr@2
   465
      BOOST_DEDUCED_TYPENAME CompareCons::tail_type
williamr@2
   466
    >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail());
williamr@2
   467
  }
williamr@2
   468
};
williamr@2
   469
williamr@2
   470
template
williamr@2
   471
<
williamr@2
   472
  typename KeyCons,typename Value,
williamr@2
   473
  typename ValCons,typename CompareCons
williamr@2
   474
>
williamr@2
   475
struct compare_ckey_cval:
williamr@2
   476
  mpl::if_<
williamr@2
   477
    mpl::or_<
williamr@2
   478
      is_same<KeyCons,tuples::null_type>,
williamr@2
   479
      is_same<ValCons,tuples::null_type>
williamr@2
   480
    >,
williamr@2
   481
    compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>,
williamr@2
   482
    compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons>
williamr@2
   483
  >::type
williamr@2
   484
{
williamr@2
   485
};
williamr@2
   486
williamr@2
   487
template<typename KeyCons,typename Value,typename HashCons>
williamr@2
   488
struct hash_ckey; /* fwd decl. */
williamr@2
   489
williamr@2
   490
template<typename KeyCons,typename Value,typename HashCons>
williamr@2
   491
struct hash_ckey_terminal
williamr@2
   492
{
williamr@2
   493
  static std::size_t hash(
williamr@2
   494
    const KeyCons&,const Value&,const HashCons&,std::size_t carry)
williamr@2
   495
  {
williamr@2
   496
    return carry;
williamr@2
   497
  }
williamr@2
   498
};
williamr@2
   499
williamr@2
   500
template<typename KeyCons,typename Value,typename HashCons>
williamr@2
   501
struct hash_ckey_normal
williamr@2
   502
{
williamr@2
   503
  static std::size_t hash(
williamr@2
   504
    const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0)
williamr@2
   505
  {
williamr@2
   506
    /* same hashing formula as boost::hash_combine */
williamr@2
   507
williamr@2
   508
    carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2);
williamr@2
   509
    return hash_ckey<
williamr@2
   510
      BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
williamr@2
   511
      BOOST_DEDUCED_TYPENAME HashCons::tail_type
williamr@2
   512
    >::hash(c.get_tail(),v,h.get_tail(),carry);
williamr@2
   513
  }
williamr@2
   514
};
williamr@2
   515
williamr@2
   516
template<typename KeyCons,typename Value,typename HashCons>
williamr@2
   517
struct hash_ckey:
williamr@2
   518
  mpl::if_<
williamr@2
   519
    is_same<KeyCons,tuples::null_type>,
williamr@2
   520
    hash_ckey_terminal<KeyCons,Value,HashCons>,
williamr@2
   521
    hash_ckey_normal<KeyCons,Value,HashCons>
williamr@2
   522
  >::type
williamr@2
   523
{
williamr@2
   524
};
williamr@2
   525
williamr@2
   526
template<typename ValCons,typename HashCons>
williamr@2
   527
struct hash_cval; /* fwd decl. */
williamr@2
   528
williamr@2
   529
template<typename ValCons,typename HashCons>
williamr@2
   530
struct hash_cval_terminal
williamr@2
   531
{
williamr@2
   532
  static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry)
williamr@2
   533
  {
williamr@2
   534
    return carry;
williamr@2
   535
  }
williamr@2
   536
};
williamr@2
   537
williamr@2
   538
template<typename ValCons,typename HashCons>
williamr@2
   539
struct hash_cval_normal
williamr@2
   540
{
williamr@2
   541
  static std::size_t hash(
williamr@2
   542
    const ValCons& vc,const HashCons& h,std::size_t carry=0)
williamr@2
   543
  {
williamr@2
   544
    carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2);
williamr@2
   545
    return hash_cval<
williamr@2
   546
      BOOST_DEDUCED_TYPENAME ValCons::tail_type,
williamr@2
   547
      BOOST_DEDUCED_TYPENAME HashCons::tail_type
williamr@2
   548
    >::hash(vc.get_tail(),h.get_tail(),carry);
williamr@2
   549
  }
williamr@2
   550
};
williamr@2
   551
williamr@2
   552
template<typename ValCons,typename HashCons>
williamr@2
   553
struct hash_cval:
williamr@2
   554
  mpl::if_<
williamr@2
   555
    is_same<ValCons,tuples::null_type>,
williamr@2
   556
    hash_cval_terminal<ValCons,HashCons>,
williamr@2
   557
    hash_cval_normal<ValCons,HashCons>
williamr@2
   558
  >::type
williamr@2
   559
{
williamr@2
   560
};
williamr@2
   561
williamr@2
   562
} /* namespace multi_index::detail */
williamr@2
   563
williamr@2
   564
/* composite_key_result */
williamr@2
   565
williamr@2
   566
template<typename CompositeKey>
williamr@2
   567
struct composite_key_result
williamr@2
   568
{
williamr@2
   569
  typedef CompositeKey                            composite_key_type;
williamr@2
   570
  typedef typename composite_key_type::value_type value_type;
williamr@2
   571
williamr@2
   572
  composite_key_result(
williamr@2
   573
    const composite_key_type& composite_key_,const value_type& value_):
williamr@2
   574
    composite_key(composite_key_),value(value_)
williamr@2
   575
  {}
williamr@2
   576
williamr@2
   577
  const composite_key_type& composite_key;
williamr@2
   578
  const value_type&         value;
williamr@2
   579
};
williamr@2
   580
williamr@2
   581
/* composite_key */
williamr@2
   582
williamr@2
   583
/* NB. Some overloads of operator() have an extra dummy parameter int=0.
williamr@2
   584
 * This disambiguator serves several purposes:
williamr@2
   585
 *  - Without it, MSVC++ 6.0 incorrectly regards some overloads as
williamr@2
   586
 *    specializations of a previous member function template.
williamr@2
   587
 *  - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
williamr@2
   588
 *    as if they have the same signature.
williamr@2
   589
 *  - If remove_const is broken due to lack of PTS, int=0 avoids the
williamr@2
   590
 *    declaration of memfuns with identical signature.
williamr@2
   591
 */
williamr@2
   592
williamr@2
   593
template<
williamr@2
   594
  typename Value,
williamr@2
   595
  BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
williamr@2
   596
>
williamr@2
   597
struct composite_key:
williamr@2
   598
  private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)>
williamr@2
   599
{
williamr@2
   600
private:
williamr@2
   601
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super;
williamr@2
   602
williamr@2
   603
public:
williamr@2
   604
  typedef super                               key_extractor_tuple;
williamr@2
   605
  typedef Value                               value_type;
williamr@2
   606
  typedef composite_key_result<composite_key> result_type;
williamr@2
   607
williamr@2
   608
  composite_key(
williamr@2
   609
    BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)):
williamr@2
   610
    super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
williamr@2
   611
  {}
williamr@2
   612
williamr@2
   613
  composite_key(const key_extractor_tuple& x):super(x){}
williamr@2
   614
williamr@2
   615
  const key_extractor_tuple& key_extractors()const{return *this;}
williamr@2
   616
  key_extractor_tuple&       key_extractors(){return *this;}
williamr@2
   617
williamr@2
   618
  template<typename ChainedPtr>
williamr@2
   619
williamr@2
   620
#if !defined(BOOST_NO_SFINAE)
williamr@2
   621
  typename disable_if<
williamr@2
   622
    is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
williamr@2
   623
#else
williamr@2
   624
  result_type
williamr@2
   625
#endif
williamr@2
   626
williamr@2
   627
  operator()(const ChainedPtr& x)const
williamr@2
   628
  {
williamr@2
   629
    return operator()(*x);
williamr@2
   630
  }
williamr@2
   631
williamr@2
   632
  result_type operator()(const value_type& x)const
williamr@2
   633
  {
williamr@2
   634
    return result_type(*this,x);
williamr@2
   635
  }
williamr@2
   636
williamr@2
   637
  result_type operator()(const reference_wrapper<const value_type>& x)const
williamr@2
   638
  {
williamr@2
   639
    return result_type(*this,x.get());
williamr@2
   640
  }
williamr@2
   641
williamr@2
   642
  result_type operator()(const reference_wrapper<value_type>& x,int=0)const
williamr@2
   643
  {
williamr@2
   644
    return result_type(*this,x.get());
williamr@2
   645
  }
williamr@2
   646
};
williamr@2
   647
williamr@2
   648
/* comparison operators */
williamr@2
   649
williamr@2
   650
/* == */
williamr@2
   651
williamr@2
   652
template<typename CompositeKey1,typename CompositeKey2>
williamr@2
   653
inline bool operator==(
williamr@2
   654
  const composite_key_result<CompositeKey1>& x,
williamr@2
   655
  const composite_key_result<CompositeKey2>& y)
williamr@2
   656
{
williamr@2
   657
  typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
williamr@2
   658
  typedef typename CompositeKey1::value_type          value_type1;
williamr@2
   659
  typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
williamr@2
   660
  typedef typename CompositeKey2::value_type          value_type2;
williamr@2
   661
williamr@2
   662
  BOOST_STATIC_ASSERT(
williamr@2
   663
    tuples::length<key_extractor_tuple1>::value==
williamr@2
   664
    tuples::length<key_extractor_tuple2>::value);
williamr@2
   665
williamr@2
   666
  return detail::equal_ckey_ckey<
williamr@2
   667
    key_extractor_tuple1,value_type1,
williamr@2
   668
    key_extractor_tuple2,value_type2,
williamr@2
   669
    detail::generic_operator_equal_tuple
williamr@2
   670
  >::compare(
williamr@2
   671
    x.composite_key.key_extractors(),x.value,
williamr@2
   672
    y.composite_key.key_extractors(),y.value,
williamr@2
   673
    detail::generic_operator_equal_tuple());
williamr@2
   674
}
williamr@2
   675
williamr@2
   676
template<
williamr@2
   677
  typename CompositeKey,
williamr@2
   678
  BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
williamr@2
   679
>
williamr@2
   680
inline bool operator==(
williamr@2
   681
  const composite_key_result<CompositeKey>& x,
williamr@2
   682
  const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
williamr@2
   683
{
williamr@2
   684
  typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
   685
  typedef typename CompositeKey::value_type              value_type;
williamr@2
   686
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
   687
  
williamr@2
   688
  BOOST_STATIC_ASSERT(
williamr@2
   689
    tuples::length<key_extractor_tuple>::value==
williamr@2
   690
    tuples::length<key_tuple>::value);
williamr@2
   691
williamr@2
   692
  return detail::equal_ckey_cval<
williamr@2
   693
    key_extractor_tuple,value_type,
williamr@2
   694
    key_tuple,detail::generic_operator_equal_tuple
williamr@2
   695
  >::compare(
williamr@2
   696
    x.composite_key.key_extractors(),x.value,
williamr@2
   697
    y,detail::generic_operator_equal_tuple());
williamr@2
   698
}
williamr@2
   699
williamr@2
   700
template
williamr@2
   701
<
williamr@2
   702
  BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
williamr@2
   703
  typename CompositeKey
williamr@2
   704
>
williamr@2
   705
inline bool operator==(
williamr@2
   706
  const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
williamr@2
   707
  const composite_key_result<CompositeKey>& y)
williamr@2
   708
{
williamr@2
   709
  typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
   710
  typedef typename CompositeKey::value_type              value_type;
williamr@2
   711
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
   712
  
williamr@2
   713
  BOOST_STATIC_ASSERT(
williamr@2
   714
    tuples::length<key_extractor_tuple>::value==
williamr@2
   715
    tuples::length<key_tuple>::value);
williamr@2
   716
williamr@2
   717
  return detail::equal_ckey_cval<
williamr@2
   718
    key_extractor_tuple,value_type,
williamr@2
   719
    key_tuple,detail::generic_operator_equal_tuple
williamr@2
   720
  >::compare(
williamr@2
   721
    x,y.composite_key.key_extractors(),
williamr@2
   722
    y.value,detail::generic_operator_equal_tuple());
williamr@2
   723
}
williamr@2
   724
williamr@2
   725
/* < */
williamr@2
   726
williamr@2
   727
template<typename CompositeKey1,typename CompositeKey2>
williamr@2
   728
inline bool operator<(
williamr@2
   729
  const composite_key_result<CompositeKey1>& x,
williamr@2
   730
  const composite_key_result<CompositeKey2>& y)
williamr@2
   731
{
williamr@2
   732
  typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
williamr@2
   733
  typedef typename CompositeKey1::value_type          value_type1;
williamr@2
   734
  typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
williamr@2
   735
  typedef typename CompositeKey2::value_type          value_type2;
williamr@2
   736
williamr@2
   737
  return detail::compare_ckey_ckey<
williamr@2
   738
   key_extractor_tuple1,value_type1,
williamr@2
   739
   key_extractor_tuple2,value_type2,
williamr@2
   740
   detail::generic_operator_less_tuple
williamr@2
   741
  >::compare(
williamr@2
   742
    x.composite_key.key_extractors(),x.value,
williamr@2
   743
    y.composite_key.key_extractors(),y.value,
williamr@2
   744
    detail::generic_operator_less_tuple());
williamr@2
   745
}
williamr@2
   746
williamr@2
   747
template
williamr@2
   748
<
williamr@2
   749
  typename CompositeKey,
williamr@2
   750
  BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
williamr@2
   751
>
williamr@2
   752
inline bool operator<(
williamr@2
   753
  const composite_key_result<CompositeKey>& x,
williamr@2
   754
  const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
williamr@2
   755
{
williamr@2
   756
  typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
   757
  typedef typename CompositeKey::value_type              value_type;
williamr@2
   758
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
   759
  
williamr@2
   760
  return detail::compare_ckey_cval<
williamr@2
   761
    key_extractor_tuple,value_type,
williamr@2
   762
    key_tuple,detail::generic_operator_less_tuple
williamr@2
   763
  >::compare(
williamr@2
   764
    x.composite_key.key_extractors(),x.value,
williamr@2
   765
    y,detail::generic_operator_less_tuple());
williamr@2
   766
}
williamr@2
   767
williamr@2
   768
template
williamr@2
   769
<
williamr@2
   770
  BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
williamr@2
   771
  typename CompositeKey
williamr@2
   772
>
williamr@2
   773
inline bool operator<(
williamr@2
   774
  const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
williamr@2
   775
  const composite_key_result<CompositeKey>& y)
williamr@2
   776
{
williamr@2
   777
  typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
   778
  typedef typename CompositeKey::value_type              value_type;
williamr@2
   779
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
   780
  
williamr@2
   781
  return detail::compare_ckey_cval<
williamr@2
   782
    key_extractor_tuple,value_type,
williamr@2
   783
    key_tuple,detail::generic_operator_less_tuple
williamr@2
   784
  >::compare(
williamr@2
   785
    x,y.composite_key.key_extractors(),
williamr@2
   786
    y.value,detail::generic_operator_less_tuple());
williamr@2
   787
}
williamr@2
   788
williamr@2
   789
/* rest of comparison operators */
williamr@2
   790
williamr@2
   791
#define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2)                  \
williamr@2
   792
template<t1,t2> inline bool operator!=(const a1& x,const a2& y)              \
williamr@2
   793
{                                                                            \
williamr@2
   794
  return !(x==y);                                                            \
williamr@2
   795
}                                                                            \
williamr@2
   796
                                                                             \
williamr@2
   797
template<t1,t2> inline bool operator>(const a1& x,const a2& y)               \
williamr@2
   798
{                                                                            \
williamr@2
   799
  return y<x;                                                                \
williamr@2
   800
}                                                                            \
williamr@2
   801
                                                                             \
williamr@2
   802
template<t1,t2> inline bool operator>=(const a1& x,const a2& y)              \
williamr@2
   803
{                                                                            \
williamr@2
   804
  return !(x<y);                                                             \
williamr@2
   805
}                                                                            \
williamr@2
   806
                                                                             \
williamr@2
   807
template<t1,t2> inline bool operator<=(const a1& x,const a2& y)              \
williamr@2
   808
{                                                                            \
williamr@2
   809
  return !(y<x);                                                             \
williamr@2
   810
}
williamr@2
   811
williamr@2
   812
BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
williamr@2
   813
  typename CompositeKey1,
williamr@2
   814
  typename CompositeKey2,
williamr@2
   815
  composite_key_result<CompositeKey1>,
williamr@2
   816
  composite_key_result<CompositeKey2>
williamr@2
   817
)
williamr@2
   818
williamr@2
   819
BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
williamr@2
   820
  typename CompositeKey,
williamr@2
   821
  BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
williamr@2
   822
  composite_key_result<CompositeKey>,
williamr@2
   823
  tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>
williamr@2
   824
)
williamr@2
   825
williamr@2
   826
BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
williamr@2
   827
  BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
williamr@2
   828
  typename CompositeKey,
williamr@2
   829
  tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>,
williamr@2
   830
  composite_key_result<CompositeKey>
williamr@2
   831
)
williamr@2
   832
williamr@2
   833
/* composite_key_equal_to */
williamr@2
   834
williamr@2
   835
template
williamr@2
   836
<
williamr@2
   837
  BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred)
williamr@2
   838
>
williamr@2
   839
struct composite_key_equal_to:
williamr@2
   840
  private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)>
williamr@2
   841
{
williamr@2
   842
private:
williamr@2
   843
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super;
williamr@2
   844
williamr@2
   845
public:
williamr@2
   846
  typedef super key_eq_tuple;
williamr@2
   847
williamr@2
   848
  composite_key_equal_to(
williamr@2
   849
    BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)):
williamr@2
   850
    super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
williamr@2
   851
  {}
williamr@2
   852
williamr@2
   853
  composite_key_equal_to(const key_eq_tuple& x):super(x){}
williamr@2
   854
williamr@2
   855
  const key_eq_tuple& key_eqs()const{return *this;}
williamr@2
   856
  key_eq_tuple&       key_eqs(){return *this;}
williamr@2
   857
williamr@2
   858
  template<typename CompositeKey1,typename CompositeKey2>
williamr@2
   859
  bool operator()(
williamr@2
   860
    const composite_key_result<CompositeKey1> & x,
williamr@2
   861
    const composite_key_result<CompositeKey2> & y)const
williamr@2
   862
  {
williamr@2
   863
    typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
williamr@2
   864
    typedef typename CompositeKey1::value_type          value_type1;
williamr@2
   865
    typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
williamr@2
   866
    typedef typename CompositeKey2::value_type          value_type2;
williamr@2
   867
williamr@2
   868
    BOOST_STATIC_ASSERT(
williamr@2
   869
      tuples::length<key_extractor_tuple1>::value<=
williamr@2
   870
      tuples::length<key_eq_tuple>::value&&
williamr@2
   871
      tuples::length<key_extractor_tuple1>::value==
williamr@2
   872
      tuples::length<key_extractor_tuple2>::value);
williamr@2
   873
williamr@2
   874
    return detail::equal_ckey_ckey<
williamr@2
   875
      key_extractor_tuple1,value_type1,
williamr@2
   876
      key_extractor_tuple2,value_type2,
williamr@2
   877
      key_eq_tuple
williamr@2
   878
    >::compare(
williamr@2
   879
      x.composite_key.key_extractors(),x.value,
williamr@2
   880
      y.composite_key.key_extractors(),y.value,
williamr@2
   881
      key_eqs());
williamr@2
   882
  }
williamr@2
   883
  
williamr@2
   884
  template
williamr@2
   885
  <
williamr@2
   886
    typename CompositeKey,
williamr@2
   887
    BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
williamr@2
   888
  >
williamr@2
   889
  bool operator()(
williamr@2
   890
    const composite_key_result<CompositeKey>& x,
williamr@2
   891
    const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
williamr@2
   892
  {
williamr@2
   893
    typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
   894
    typedef typename CompositeKey::value_type              value_type;
williamr@2
   895
    typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
   896
williamr@2
   897
    BOOST_STATIC_ASSERT(
williamr@2
   898
      tuples::length<key_extractor_tuple>::value<=
williamr@2
   899
      tuples::length<key_eq_tuple>::value&&
williamr@2
   900
      tuples::length<key_extractor_tuple>::value==
williamr@2
   901
      tuples::length<key_tuple>::value);
williamr@2
   902
williamr@2
   903
    return detail::equal_ckey_cval<
williamr@2
   904
      key_extractor_tuple,value_type,
williamr@2
   905
      key_tuple,key_eq_tuple
williamr@2
   906
    >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs());
williamr@2
   907
  }
williamr@2
   908
williamr@2
   909
  template
williamr@2
   910
  <
williamr@2
   911
    BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
williamr@2
   912
    typename CompositeKey
williamr@2
   913
  >
williamr@2
   914
  bool operator()(
williamr@2
   915
    const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
williamr@2
   916
    const composite_key_result<CompositeKey>& y)const
williamr@2
   917
  {
williamr@2
   918
    typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
   919
    typedef typename CompositeKey::value_type              value_type;
williamr@2
   920
    typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
   921
williamr@2
   922
    BOOST_STATIC_ASSERT(
williamr@2
   923
      tuples::length<key_tuple>::value<=
williamr@2
   924
      tuples::length<key_eq_tuple>::value&&
williamr@2
   925
      tuples::length<key_tuple>::value==
williamr@2
   926
      tuples::length<key_extractor_tuple>::value);
williamr@2
   927
williamr@2
   928
    return detail::equal_ckey_cval<
williamr@2
   929
      key_extractor_tuple,value_type,
williamr@2
   930
      key_tuple,key_eq_tuple
williamr@2
   931
    >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs());
williamr@2
   932
  }
williamr@2
   933
};
williamr@2
   934
williamr@2
   935
/* composite_key_compare */
williamr@2
   936
williamr@2
   937
template
williamr@2
   938
<
williamr@2
   939
  BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare)
williamr@2
   940
>
williamr@2
   941
struct composite_key_compare:
williamr@2
   942
  private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)>
williamr@2
   943
{
williamr@2
   944
private:
williamr@2
   945
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> super;
williamr@2
   946
williamr@2
   947
public:
williamr@2
   948
  typedef super key_comp_tuple;
williamr@2
   949
williamr@2
   950
  composite_key_compare(
williamr@2
   951
    BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)):
williamr@2
   952
    super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
williamr@2
   953
  {}
williamr@2
   954
williamr@2
   955
  composite_key_compare(const key_comp_tuple& x):super(x){}
williamr@2
   956
williamr@2
   957
  const key_comp_tuple& key_comps()const{return *this;}
williamr@2
   958
  key_comp_tuple&       key_comps(){return *this;}
williamr@2
   959
williamr@2
   960
  template<typename CompositeKey1,typename CompositeKey2>
williamr@2
   961
  bool operator()(
williamr@2
   962
    const composite_key_result<CompositeKey1> & x,
williamr@2
   963
    const composite_key_result<CompositeKey2> & y)const
williamr@2
   964
  {
williamr@2
   965
    typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
williamr@2
   966
    typedef typename CompositeKey1::value_type          value_type1;
williamr@2
   967
    typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
williamr@2
   968
    typedef typename CompositeKey2::value_type          value_type2;
williamr@2
   969
williamr@2
   970
    BOOST_STATIC_ASSERT(
williamr@2
   971
      tuples::length<key_extractor_tuple1>::value<=
williamr@2
   972
      tuples::length<key_comp_tuple>::value||
williamr@2
   973
      tuples::length<key_extractor_tuple2>::value<=
williamr@2
   974
      tuples::length<key_comp_tuple>::value);
williamr@2
   975
williamr@2
   976
    return detail::compare_ckey_ckey<
williamr@2
   977
      key_extractor_tuple1,value_type1,
williamr@2
   978
      key_extractor_tuple2,value_type2,
williamr@2
   979
      key_comp_tuple
williamr@2
   980
    >::compare(
williamr@2
   981
      x.composite_key.key_extractors(),x.value,
williamr@2
   982
      y.composite_key.key_extractors(),y.value,
williamr@2
   983
      key_comps());
williamr@2
   984
  }
williamr@2
   985
  
williamr@2
   986
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
williamr@2
   987
  template<typename CompositeKey,typename Value>
williamr@2
   988
  bool operator()(
williamr@2
   989
    const composite_key_result<CompositeKey>& x,
williamr@2
   990
    const Value& y)const
williamr@2
   991
  {
williamr@2
   992
    return operator()(x,make_tuple(cref(y)));
williamr@2
   993
  }
williamr@2
   994
#endif
williamr@2
   995
williamr@2
   996
  template
williamr@2
   997
  <
williamr@2
   998
    typename CompositeKey,
williamr@2
   999
    BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
williamr@2
  1000
  >
williamr@2
  1001
  bool operator()(
williamr@2
  1002
    const composite_key_result<CompositeKey>& x,
williamr@2
  1003
    const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
williamr@2
  1004
  {
williamr@2
  1005
    typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
  1006
    typedef typename CompositeKey::value_type              value_type;
williamr@2
  1007
    typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
  1008
williamr@2
  1009
    BOOST_STATIC_ASSERT(
williamr@2
  1010
      tuples::length<key_extractor_tuple>::value<=
williamr@2
  1011
      tuples::length<key_comp_tuple>::value||
williamr@2
  1012
      tuples::length<key_tuple>::value<=
williamr@2
  1013
      tuples::length<key_comp_tuple>::value);
williamr@2
  1014
williamr@2
  1015
    return detail::compare_ckey_cval<
williamr@2
  1016
      key_extractor_tuple,value_type,
williamr@2
  1017
      key_tuple,key_comp_tuple
williamr@2
  1018
    >::compare(x.composite_key.key_extractors(),x.value,y,key_comps());
williamr@2
  1019
  }
williamr@2
  1020
williamr@2
  1021
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
williamr@2
  1022
  template<typename Value,typename CompositeKey>
williamr@2
  1023
  bool operator()(
williamr@2
  1024
    const Value& x,
williamr@2
  1025
    const composite_key_result<CompositeKey>& y)const
williamr@2
  1026
  {
williamr@2
  1027
    return operator()(make_tuple(cref(x)),y);
williamr@2
  1028
  }
williamr@2
  1029
#endif
williamr@2
  1030
williamr@2
  1031
  template
williamr@2
  1032
  <
williamr@2
  1033
    BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
williamr@2
  1034
    typename CompositeKey
williamr@2
  1035
  >
williamr@2
  1036
  bool operator()(
williamr@2
  1037
    const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
williamr@2
  1038
    const composite_key_result<CompositeKey>& y)const
williamr@2
  1039
  {
williamr@2
  1040
    typedef typename CompositeKey::key_extractor_tuple     key_extractor_tuple;
williamr@2
  1041
    typedef typename CompositeKey::value_type              value_type;
williamr@2
  1042
    typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
  1043
williamr@2
  1044
    BOOST_STATIC_ASSERT(
williamr@2
  1045
      tuples::length<key_tuple>::value<=
williamr@2
  1046
      tuples::length<key_comp_tuple>::value||
williamr@2
  1047
      tuples::length<key_extractor_tuple>::value<=
williamr@2
  1048
      tuples::length<key_comp_tuple>::value);
williamr@2
  1049
williamr@2
  1050
    return detail::compare_ckey_cval<
williamr@2
  1051
      key_extractor_tuple,value_type,
williamr@2
  1052
      key_tuple,key_comp_tuple
williamr@2
  1053
    >::compare(x,y.composite_key.key_extractors(),y.value,key_comps());
williamr@2
  1054
  }
williamr@2
  1055
};
williamr@2
  1056
williamr@2
  1057
/* composite_key_hash */
williamr@2
  1058
williamr@2
  1059
template
williamr@2
  1060
<
williamr@2
  1061
  BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash)
williamr@2
  1062
>
williamr@2
  1063
struct composite_key_hash:
williamr@2
  1064
  private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)>
williamr@2
  1065
{
williamr@2
  1066
private:
williamr@2
  1067
  typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> super;
williamr@2
  1068
williamr@2
  1069
public:
williamr@2
  1070
  typedef super key_hasher_tuple;
williamr@2
  1071
williamr@2
  1072
  composite_key_hash(
williamr@2
  1073
    BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)):
williamr@2
  1074
    super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
williamr@2
  1075
  {}
williamr@2
  1076
williamr@2
  1077
  composite_key_hash(const key_hasher_tuple& x):super(x){}
williamr@2
  1078
williamr@2
  1079
  const key_hasher_tuple& key_hash_functions()const{return *this;}
williamr@2
  1080
  key_hasher_tuple&       key_hash_functions(){return *this;}
williamr@2
  1081
williamr@2
  1082
  template<typename CompositeKey>
williamr@2
  1083
  std::size_t operator()(const composite_key_result<CompositeKey> & x)const
williamr@2
  1084
  {
williamr@2
  1085
    typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
williamr@2
  1086
    typedef typename CompositeKey::value_type          value_type;
williamr@2
  1087
williamr@2
  1088
    BOOST_STATIC_ASSERT(
williamr@2
  1089
      tuples::length<key_extractor_tuple>::value==
williamr@2
  1090
      tuples::length<key_hasher_tuple>::value);
williamr@2
  1091
williamr@2
  1092
    return detail::hash_ckey<
williamr@2
  1093
      key_extractor_tuple,value_type,
williamr@2
  1094
      key_hasher_tuple
williamr@2
  1095
    >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions());
williamr@2
  1096
  }
williamr@2
  1097
  
williamr@2
  1098
  template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)>
williamr@2
  1099
  std::size_t operator()(
williamr@2
  1100
    const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const
williamr@2
  1101
  {
williamr@2
  1102
    typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
williamr@2
  1103
williamr@2
  1104
    BOOST_STATIC_ASSERT(
williamr@2
  1105
      tuples::length<key_tuple>::value==
williamr@2
  1106
      tuples::length<key_hasher_tuple>::value);
williamr@2
  1107
williamr@2
  1108
    return detail::hash_cval<
williamr@2
  1109
      key_tuple,key_hasher_tuple
williamr@2
  1110
    >::hash(x,key_hash_functions());
williamr@2
  1111
  }
williamr@2
  1112
};
williamr@2
  1113
williamr@2
  1114
/* Instantiations of the former functors with "natural" basic components:
williamr@2
  1115
 * composite_key_result_equal_to uses std::equal_to of the values.
williamr@2
  1116
 * composite_key_result_less     uses std::less.
williamr@2
  1117
 * composite_key_result_greater  uses std::greater.
williamr@2
  1118
 * composite_key_result_hash     uses boost::hash.
williamr@2
  1119
 */
williamr@2
  1120
williamr@2
  1121
#define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER                           \
williamr@2
  1122
composite_key_equal_to<                                                      \
williamr@2
  1123
    BOOST_MULTI_INDEX_CK_ENUM(                                               \
williamr@2
  1124
      BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N,                             \
williamr@2
  1125
      /* the argument is a PP list */                                        \
williamr@2
  1126
      (detail::nth_composite_key_equal_to,                                   \
williamr@2
  1127
        (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type,      \
williamr@2
  1128
          BOOST_PP_NIL)))                                                    \
williamr@2
  1129
  >
williamr@2
  1130
williamr@2
  1131
template<typename CompositeKeyResult>
williamr@2
  1132
struct composite_key_result_equal_to:
williamr@2
  1133
BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
williamr@2
  1134
BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
williamr@2
  1135
{
williamr@2
  1136
private:
williamr@2
  1137
  typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super;
williamr@2
  1138
williamr@2
  1139
public:
williamr@2
  1140
  typedef CompositeKeyResult  first_argument_type;
williamr@2
  1141
  typedef first_argument_type second_argument_type;
williamr@2
  1142
  typedef bool                result_type;
williamr@2
  1143
williamr@2
  1144
  using super::operator();
williamr@2
  1145
};
williamr@2
  1146
williamr@2
  1147
#define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER                               \
williamr@2
  1148
composite_key_compare<                                                       \
williamr@2
  1149
    BOOST_MULTI_INDEX_CK_ENUM(                                               \
williamr@2
  1150
      BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N,                             \
williamr@2
  1151
      /* the argument is a PP list */                                        \
williamr@2
  1152
      (detail::nth_composite_key_less,                                       \
williamr@2
  1153
        (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type,      \
williamr@2
  1154
          BOOST_PP_NIL)))                                                    \
williamr@2
  1155
  >
williamr@2
  1156
williamr@2
  1157
template<typename CompositeKeyResult>
williamr@2
  1158
struct composite_key_result_less:
williamr@2
  1159
BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
williamr@2
  1160
BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
williamr@2
  1161
{
williamr@2
  1162
private:
williamr@2
  1163
  typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super;
williamr@2
  1164
williamr@2
  1165
public:
williamr@2
  1166
  typedef CompositeKeyResult  first_argument_type;
williamr@2
  1167
  typedef first_argument_type second_argument_type;
williamr@2
  1168
  typedef bool                result_type;
williamr@2
  1169
williamr@2
  1170
  using super::operator();
williamr@2
  1171
};
williamr@2
  1172
williamr@2
  1173
#define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER                            \
williamr@2
  1174
composite_key_compare<                                                       \
williamr@2
  1175
    BOOST_MULTI_INDEX_CK_ENUM(                                               \
williamr@2
  1176
      BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N,                             \
williamr@2
  1177
      /* the argument is a PP list */                                        \
williamr@2
  1178
      (detail::nth_composite_key_greater,                                    \
williamr@2
  1179
        (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type,      \
williamr@2
  1180
          BOOST_PP_NIL)))                                                    \
williamr@2
  1181
  >
williamr@2
  1182
williamr@2
  1183
template<typename CompositeKeyResult>
williamr@2
  1184
struct composite_key_result_greater:
williamr@2
  1185
BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
williamr@2
  1186
BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
williamr@2
  1187
{
williamr@2
  1188
private:
williamr@2
  1189
  typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super;
williamr@2
  1190
williamr@2
  1191
public:
williamr@2
  1192
  typedef CompositeKeyResult  first_argument_type;
williamr@2
  1193
  typedef first_argument_type second_argument_type;
williamr@2
  1194
  typedef bool                result_type;
williamr@2
  1195
williamr@2
  1196
  using super::operator();
williamr@2
  1197
};
williamr@2
  1198
williamr@2
  1199
#define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER                               \
williamr@2
  1200
composite_key_hash<                                                          \
williamr@2
  1201
    BOOST_MULTI_INDEX_CK_ENUM(                                               \
williamr@2
  1202
      BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N,                             \
williamr@2
  1203
      /* the argument is a PP list */                                        \
williamr@2
  1204
      (detail::nth_composite_key_hash,                                       \
williamr@2
  1205
        (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type,      \
williamr@2
  1206
          BOOST_PP_NIL)))                                                    \
williamr@2
  1207
  >
williamr@2
  1208
williamr@2
  1209
template<typename CompositeKeyResult>
williamr@2
  1210
struct composite_key_result_hash:
williamr@2
  1211
BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
williamr@2
  1212
BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
williamr@2
  1213
{
williamr@2
  1214
private:
williamr@2
  1215
  typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super;
williamr@2
  1216
williamr@2
  1217
public:
williamr@2
  1218
  typedef CompositeKeyResult argument_type;
williamr@2
  1219
  typedef std::size_t        result_type;
williamr@2
  1220
williamr@2
  1221
  using super::operator();
williamr@2
  1222
};
williamr@2
  1223
williamr@2
  1224
} /* namespace multi_index */
williamr@2
  1225
williamr@2
  1226
} /* namespace boost */
williamr@2
  1227
williamr@2
  1228
/* Specializations of std::equal_to, std::less, std::greater and boost::hash
williamr@2
  1229
 * for composite_key_results enabling interoperation with tuples of values.
williamr@2
  1230
 */
williamr@2
  1231
williamr@2
  1232
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
williamr@2
  1233
namespace std{
williamr@2
  1234
williamr@2
  1235
template<typename CompositeKey>
williamr@2
  1236
struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >:
williamr@2
  1237
  boost::multi_index::composite_key_result_equal_to<
williamr@2
  1238
    boost::multi_index::composite_key_result<CompositeKey>
williamr@2
  1239
  >
williamr@2
  1240
{
williamr@2
  1241
};
williamr@2
  1242
williamr@2
  1243
template<typename CompositeKey>
williamr@2
  1244
struct less<boost::multi_index::composite_key_result<CompositeKey> >:
williamr@2
  1245
  boost::multi_index::composite_key_result_less<
williamr@2
  1246
    boost::multi_index::composite_key_result<CompositeKey>
williamr@2
  1247
  >
williamr@2
  1248
{
williamr@2
  1249
};
williamr@2
  1250
williamr@2
  1251
template<typename CompositeKey>
williamr@2
  1252
struct greater<boost::multi_index::composite_key_result<CompositeKey> >:
williamr@2
  1253
  boost::multi_index::composite_key_result_greater<
williamr@2
  1254
    boost::multi_index::composite_key_result<CompositeKey>
williamr@2
  1255
  >
williamr@2
  1256
{
williamr@2
  1257
};
williamr@2
  1258
williamr@2
  1259
} /* namespace std */
williamr@2
  1260
williamr@2
  1261
namespace boost{
williamr@2
  1262
williamr@2
  1263
template<typename CompositeKey>
williamr@2
  1264
struct hash<boost::multi_index::composite_key_result<CompositeKey> >:
williamr@2
  1265
  boost::multi_index::composite_key_result_hash<
williamr@2
  1266
    boost::multi_index::composite_key_result<CompositeKey>
williamr@2
  1267
  >
williamr@2
  1268
{
williamr@2
  1269
};
williamr@2
  1270
williamr@2
  1271
} /* namespace boost */
williamr@2
  1272
#else
williamr@2
  1273
/* Lacking template partial specialization, std::equal_to, std::less and
williamr@2
  1274
 * std::greater will still work for composite_key_results although without
williamr@2
  1275
 * tuple interoperability. To achieve the same graceful degrading with
williamr@2
  1276
 * boost::hash, we define the appropriate hash_value overload.
williamr@2
  1277
 */
williamr@2
  1278
williamr@2
  1279
namespace boost{
williamr@2
  1280
williamr@2
  1281
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
williamr@2
  1282
namespace multi_index{
williamr@2
  1283
#endif
williamr@2
  1284
williamr@2
  1285
template<typename CompositeKey>
williamr@2
  1286
inline std::size_t hash_value(
williamr@2
  1287
  const boost::multi_index::composite_key_result<CompositeKey>& x)
williamr@2
  1288
{
williamr@2
  1289
  boost::multi_index::composite_key_result_hash<
williamr@2
  1290
    boost::multi_index::composite_key_result<CompositeKey> > h;
williamr@2
  1291
  return h(x);
williamr@2
  1292
}
williamr@2
  1293
williamr@2
  1294
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
williamr@2
  1295
} /* namespace multi_index */
williamr@2
  1296
#endif
williamr@2
  1297
williamr@2
  1298
} /* namespace boost */
williamr@2
  1299
#endif
williamr@2
  1300
williamr@2
  1301
#undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
williamr@2
  1302
#undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
williamr@2
  1303
#undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
williamr@2
  1304
#undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
williamr@2
  1305
#undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS
williamr@2
  1306
#undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO
williamr@2
  1307
#undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR
williamr@2
  1308
#undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N
williamr@2
  1309
#undef BOOST_MULTI_INDEX_CK_CTOR_ARG
williamr@2
  1310
#undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM
williamr@2
  1311
#undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS
williamr@2
  1312
#undef BOOST_MULTI_INDEX_CK_ENUM
williamr@2
  1313
#undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE
williamr@2
  1314
williamr@2
  1315
#endif