# Boost.MultiIndex Key extraction reference

Random access indices
Boost.MultiIndex reference
Compiler specifics

## Contents

- Key Extractors
  - Chained pointers
- Header `"boost/multi_index/key_extractors.hpp"` synopsis
- Header `"boost/multi_index/identity.hpp"` synopsis
  - Class template `identity`
- Header `"boost/multi_index/member.hpp"` synopsis
  - Class template `member`
  - Class template `member_offset`
  - Macro `BOOST_MULTI_INDEX_MEMBER`
- Header `"boost/multi_index/mem_fun.hpp"` synopsis
  - Class template `const_mem_fun`
  - Class templates `cv_mem_fun`, `cref_mem_fun` and `cvref_mem_fun`
  - Class template `mem_fun`
  - Class templates `volatile_mem_fun`, `ref_mem_fun` and `vref_mem_fun`
  - Class templates `const_mem_fun_explicit` and `mem_fun_explicit`
  - Macros `BOOST_MULTI_INDEX_CONST_MEM_FUN` and `BOOST_MULTI_INDEX_MEM_FUN`
- Header `"boost/multi_index/global_fun.hpp"` synopsis
  - Class template `global_fun`
- Header `"boost/multi_index/composite_key.hpp"` synopsis
  - Class template `composite_key`
  - Class template `composite_key_result`
  - Equality
    - Class template `composite_key_equal_to`
    - Class template `composite_key_result_equal_to`
    - Specialization of `std::equal_to` for `composite_key` results
  - Comparison
    - Class template `composite_key_compare`
    - Class template `composite_key_result_less`
    - Class template `composite_key_result_greater`
    - Specialization of `std::less` for `composite_key` results
    - Specialization of `std::greater` for `composite_key` results
  - Hashing
    - Class template `composite_key_hash`
    - Class template `composite_key_result_hash`
    - Specialization of `boost::hash` for `composite_key` results
  - Semantics of `composite_key_result`
- Header `"boost/multi_index/key.hpp"` synopsis
  - Alias template `key`

## Key Extractors

Key extraction classes are used by key-based indices to obtain the indexing keys from the elements of a `multi_index_container`. A `CopyConstructible` and `CopyAssignable` class `KeyFromValue` is said to be a key extractor from a type `Type` if

1. the type `KeyFromValue::result_type` is defined,
2. `k1(ca)` is defined and returns a value convertible to `const KeyFromValue::result_type&`,
3. if `k2` is a copy of `k1`, `k1(ca)` is the same value as `k2(ca)`,

for every `k1`, `k2` of type `const KeyFromValue`, and `ca` of type `const Type&`.

Additionally, `KeyFromValue` is a read/write key extractor if the following extra conditions are met:

1. `remove_reference_t<KeyFromValue::result_type>` is not `const`-qualified.
2. `k1(a)` is defined and returns a value convertible to `KeyFromValue::result_type&`,
3. `k1(a)` is bound to the same object as `k1(const_cast<const Type&>(a))`,

for every `k1` of type `const KeyFromValue` and `a` of type `Type&`.

Boost.MultiIndex provides twelve general-purpose key extractors:

- `identity`,
- `member`,
- `const_mem_fun` (and three variants),
- `mem_fun` (and three variants),
- `global_fun` and
- `composite_key`,

plus, in C++17 compliant environments, an alias template `key` allowing for a very terse specification of the previous extractors (except `identity`).

### Chained pointers

The key extractors provided by Boost.MultiIndex are templatized according to the type `Type` and serve to extract keys not only from objects of type `Type`, but also from reference wrappers provided by Boost.Ref and from chained pointers to `Type` (or to reference wrappers of `Type`): a chained pointer is any type `P` such that, for an object `p` of type `const P`

- `*p` yields an object of type `Type&` or `boost::reference_wrapper<Type>`, OR
- `*p` yields a chained pointer to `Type`,

that is, chained pointers are arbitrary compositions of pointer-like objects ultimately dereferencing to values of `Type&` or `boost::reference_wrapper<Type>`.

## Header `"boost/multi_index/key_extractors.hpp"` synopsis

>     #include <boost/multi_index/identity.hpp>
>     #include <boost/multi_index/member.hpp>
>     #include <boost/multi_index/mem_fun.hpp>
>     #include <boost/multi_index/global_fun.hpp>
>     #include <boost/multi_index/composite_key.hpp>

This header includes all the key extractors provided by Boost.MultiIndex.

## Header `"boost/multi_index/identity.hpp"` synopsis

>     namespace boost{

>     namespace multi_index{

>     template<typename T> struct identity;

>     } // namespace boost::multi_index

>     } // namespace boost

### Class template `identity`

`identity` is a `Key Extractor` that acts as a do-nothing identity functor.

>     template<typename Type>
>     struct identity
>     {
>       typedef Type result_type;

>       // only provided if const ChainedPtr& is not convertible to const Type&
>       template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const;

>       const Type& operator()(const Type& x)const;
>       Type&       operator()(Type& x)const; // only provided if Type is non-const

>       // only provided if Type is non-const
>       const Type& operator()(const reference_wrapper<const Type>& x)const;

>       // only provided if Type is const
>       Type& operator()(
>         const reference_wrapper<typename remove_const<Type>::type>& x)const;

>       Type& operator()(const reference_wrapper<Type>& x)const;
>     };

`identity<Type>` is a model of:

- read/write `Key Extractor` from `Type`,
- `Key Extractor` from `reference_wrapper<const Type>`,
- read/write `Key Extractor` from `reference_wrapper<Type>`,
- `Key Extractor` from any chained pointer to `const Type`,
- read/write `Key Extractor` from any chained pointer to `Type`.

#### `identity` members

`template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const;`

> Requires: `ChainedPtr` is a chained pointer type to `Type`.
> Returns: a reference to the object chained-pointed to by `x`.

`const Type& operator()(const Type& x)const;`

> Returns: `x`.

`Type& operator()(Type& x)const;`

> Returns: `x`.

`const Type& operator()(const reference_wrapper<const Type>& x)const;`

> Returns: `x.get()`.

`Type& operator()(const reference_wrapper<typename remove_const<Type>::type>& x)const;`

> Returns: `x.get()`.

`Type& operator()(const reference_wrapper<Type>& x)const;`

> Returns: `x.get()`.

## Header `"boost/multi_index/member.hpp"` synopsis

>     namespace boost{

>     namespace multi_index{

>     template<class Class,typename Type,Type Class::*PtrToMember>
>     struct member;

>     template<class Class,typename Type,std::size_t OffsetOfMember>
>     struct member_offset; // deprecated

>     #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) implementation defined

>     } // namespace boost::multi_index

>     } // namespace boost

### Class template `member`

`member` is a `Key Extractor` aimed at accessing a given member of a class.

>     template<class Class,typename Type,Type Class::*PtrToMember>
>     struct member
>     {
>       typedef Type result_type;

>       // only provided if const ChainedPtr& is not convertible to const Class&
>       template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const;

>       const Type& operator()(const Class& x)const;
>       Type&       operator()(Class& x)const; // only provided if Type is non-const
>       const Type& operator()(const reference_wrapper<const Class>& x)const;
>       Type&       operator()(const reference_wrapper<Class>& x)const;
>     };

The `PtrToMember` template argument specifies the particular `Type Class::*` pointer to the member to be extracted. `member<Class,Type,PtrToMember>` is a model of:

- `Key Extractor` from `Class`, read/write if `Type` is not `const`-qualified,
- `Key Extractor` from `reference_wrapper<const Class>`,
- `Key Extractor` from `reference_wrapper<Class>`, read/write if `Type` is not `const`-qualified,
- `Key Extractor` from any chained pointer to `const Class`,
- `Key Extractor` from any chained pointer to `Class`, read/write if `Type` is not `const`-qualified.

#### `member` members

`template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const;`

> Requires: `ChainedPtr` is a chained pointer type to `Type`.
> Returns: a reference to the object chained-pointed to by `x`.

`const Type& operator()(const Class& x)const;`

> Returns: `x.*PtrToMember`.

`Type& operator()(Class& x)const;`

> Returns: `x.*PtrToMember`.

`const Type& operator()(const reference_wrapper<const Class>& x)const;`

> Returns: `x.get().*PtrToMember`.

`Type& operator()(const reference_wrapper<Class>& x)const;`

> Returns: `x.get().*PtrToMember`.

### Class template `member_offset`

`member_offset` was designed to overcome limitations of some legacy compilers and its use is currently deprecated. Refer to a former version of Boost.MultiIndex for further information.

### Macro `BOOST_MULTI_INDEX_MEMBER`

>     BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName)

This macro was designed as a portability mechanism for legacy compilers where `member` could not be supported. As such it is no longer needed in modern environments, though some users might still prefer it to plain `member` because it provides a slightly more concise syntax.

## Header `"boost/multi_index/mem_fun.hpp"` synopsis

>     namespace boost{

>     namespace multi_index{

>     template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
>     struct const_mem_fun;

>     template<
>       class Class,typename Type,Type (Class::*PtrToMemberFunction)()const volatile
>     >
>     struct cv_mem_fun;

>     template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const&>
>     struct cref_mem_fun;

>     template<
>       class Class,typename Type,Type (Class::*PtrToMemberFunction)()const volatile&
>     >
>     struct cvref_mem_fun;

>     template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()>
>     struct mem_fun;

>     template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile>
>     struct volatile_mem_fun;

>     template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()&>
>     struct ref_mem_fun;

>     template<
>       class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile&
>     >
>     struct vref_mem_fun;

>     template<
>       class Class,typename Type,
>       typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
>     >
>     struct const_mem_fun_explicit; // deprecated

>     template<
>       class Class,typename Type,
>       typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
>     >
>     struct mem_fun_explicit;       // deprecated

>     #define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \
>     implementation defined
>     #define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \
>     implementation defined

>     } // namespace boost::multi_index

>     } // namespace boost

### Class template `const_mem_fun`

`const_mem_fun` is a `Key Extractor` returning as key the result of invoking a given constant member function of a class.

>     template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
>     struct const_mem_fun
>     {
>       typedef typename remove_reference<Type>::type result_type;

>       // only provided if const ChainedPtr& is not convertible to const Class&
>       template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const;

>       Type operator()(const Class& x)const;
>       Type operator()(const reference_wrapper<const Class>& x)const;
>       Type operator()(const reference_wrapper<Class>& x)const;
>     };

The `PtrToMemberFunction` template argument specifies the particular `Type (Class::*PtrToMemberFunction)()const` pointer to the constant member function used in the extraction. `const_mem_fun<Class,Type,PtrToMemberFunction>` is a model of:

- `Key Extractor` from `Class`,
- `Key Extractor` from `reference_wrapper<const Class>`,
- `Key Extractor` from `reference_wrapper<Class>`,
- `Key Extractor` from any chained pointer to `const Class`,
- `Key Extractor` from any chained pointer to `Class`,

and is also read/write in all these cases if `Type` is an lvalue reference to a non `const`-qualified type.

#### `const_mem_fun` members

`template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const;`

> Requires: `ChainedPtr` is a chained pointer type to `Type`.
> Returns: `(y.*PtrToMemberFunction)()`, where `y` is the object chained-pointed to by `x`.

`Type operator()(const Class& x)const;`

> Returns: `(x.*PtrToMemberFunction)()`.

`Type operator()(const reference_wrapper<const Class>& x)const;`

> Returns: `(x.get().*PtrToMemberFunction)()`.

`Type operator()(const reference_wrapper<Class>& x)const;`

> Returns: `(x.get().*PtrToMemberFunction)()`.

### Class templates `cv_mem_fun`, `cref_mem_fun` and `cvref_mem_fun`

These `Key Extractors` are variants of `const_mem_fun` used in the case that the passed member function is:

- `const volatile` (`cv_mem_fun`),
- `const &`-qualified (`cref_mem_fun`),
- `const volatile &`-qualified (`cvref_mem_fun`).

Other than this, their interface is exactly the same as that of `const_mem_fun`.

### Class template `mem_fun`

`mem_fun` is a `Key Extractor` returning as key the result of invoking a given member function of a class.

>     template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()>
>     struct mem_fun
>     {
>       typedef typename remove_reference<Type>::type result_type;

>       // only provided if ChainedPtr& is not convertible to Class&
>       template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const;

>       Type operator()(Class& x)const;
>       Type operator()(const reference_wrapper<Class>& x)const;
>     };

The `PtrToMemberFunction` template argument specifies the particular `Type (Class::*PtrToMemberFunction)()` pointer to the member function used in the extraction. `mem_fun<Class,Type,PtrToMemberFunction>` is a model of:

- `Key Extractor` from `reference_wrapper<Class>`,
- `Key Extractor` from any chained pointer to `Class`,

and is also read/write in all these cases if `Type` is an lvalue reference to a non `const`-qualified type.

#### `mem_fun` members

`template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const;`

> Requires: `ChainedPtr` is a chained pointer type to `Type`.
> Returns: `(y.*PtrToMemberFunction)()`, where `y` is the object chained-pointed to by `x`.

`Type operator()(Class& x)const;`

> Returns: `(x.*PtrToMemberFunction)()`.

`Type operator()(const reference_wrapper<Class>& x)const;`

> Returns: `(x.get().*PtrToMemberFunction)()`.

### Class templates `volatile_mem_fun`, `ref_mem_fun` and `vref_mem_fun`

These `Key Extractors` are variants of `mem_fun` used in the case that the passed member function is:

- `volatile` (`volatile_mem_fun`),
- `&`-qualified (`ref_mem_fun`),
- `volatile &`-qualified (`vref_mem_fun`).

Other than this, their interface is exactly the same as that of `mem_fun`.

### Class templates `const_mem_fun_explicit` and `mem_fun_explicit`

These extractors were provided as a workaround for MSVC++ 6.0 and are now deprecated. Refer to a former version of Boost.MultiIndex for further information.

### Macros `BOOST_MULTI_INDEX_CONST_MEM_FUN` and `BOOST_MULTI_INDEX_MEM_FUN`

>     BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName)
>     BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName)

Portability macros for usage of `const_mem_fun` and `mem_fun`. Although no longer needed in modern compilers, some users might still decide to resort to them as they provide a slightly more concise syntax.

## Header `"boost/multi_index/global_fun.hpp"` synopsis

>     namespace boost{

>     namespace multi_index{

>     template<class Value,typename Type,Type (*PtrToFunction)(Value)>
>     struct global_fun;

>     } // namespace boost::multi_index

>     } // namespace boost

### Class template `global_fun`

`global_fun` is a `Key Extractor` based on a given global or static member function accepting the base type as argument and returning the associated key.

>     template<class Value,typename Type,Type (*PtrToFunction)(Value)>
>     struct global_fun
>     {
>       typedef typename remove_reference<Type>::type result_type;

>       // Only provided under the following circumstances:
>       //   - If Value is a reference to a constant type, only provided
>       //     when const ChainedPtr& is not convertible to Value;
>       //   - if Value is a reference to a non-const type, only provided
>       //     when ChainedPtr& is not convertible to Value;
>       //   - else, only provided when const ChainedPtr& is not
>       //     convertible to const Value&.
>       Type operator()(const ChainedPtr& x)const;

>       // only provided if Value is a reference type
>       Type operator()(Value x)const;

>       // only provided if Value is not a reference type
>       Type operator()(const Value& x)const;

>       // only provided if Value is not a reference type
>       Type operator()(const reference_wrapper<const Value>& x)const;

>       // only provided if Value is a reference type
>       Type operator()(
>         const reference_wrapper<
>           remove_reference<Value>::type>& x)const;

>       // only provided if Value is not a reference type or is
>       // a reference to a constant type
>       Type operator()(
>         const reference_wrapper<
>           typename remove_const<
>             typename remove_reference<Value>::type>::type>& x)const;
>     };

`PtrToFunction` specifies the particular function used to extract the key of type `Type` from some `BaseType`. `global_fun` supports the following function signatures:

- `Type f(BaseType)` (`Value` is `BaseType`),
- `Type f(const BaseType&)` (`Value` is `const BaseType&`),
- `Type f(BaseType&)` (`Value` is `BaseType&`).

`global_fun<Type,Value,PtrToFunction>` is a model of:

- `Key Extractor` from `reference_wrapper<BaseType>`,
- `Key Extractor` from any chained pointer to `BaseType`.

When `Value` is `BaseType` or `const BaseType&`, `global_fun<Type,Value,PtrToFunction>` is also a model of:

- `Key Extractor` from `BaseType`,
- `Key Extractor` from `reference_wrapper<const BaseType>`,
- `Key Extractor` from any chained pointer to `const BaseType`.

In all the five cases above, `global_fun<Type,Value,PtrToFunction>` is also read/write if `Type` is an lvalue reference to a non `const`-qualified type.

#### `global_fun` members

`template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const;`

> Requires: `ChainedPtr` is a chained pointer type to `Value`.
> Returns: `PtrToFunction)(y)`, where `y` is the object chained-pointed to by `x`.

`Type operator()(Value x)const;`

> Returns: `PtrToFunction(x)`.

`Type operator()(const Value& x)const;`

> Returns: `PtrToFunction(x)`.

`Type operator()(const reference_wrapper<const Value>& x)const;`

> Returns: `PtrToFunction(x.get())`.

`Type operator()(
const reference_wrapper<remove_reference<Value>::type>& x)const;`

> Returns: `PtrToFunction(x.get())`.

`Type operator()(
const reference_wrapper<
typename remove_const<
typename remove_reference<Value>::type>::type>& x)const;`

> Returns: `PtrToFunction(x.get())`.

## Header `"boost/multi_index/composite_key.hpp"` synopsis

>     namespace boost{

>     namespace multi_index{

>     template<typename Value,typename KeyFromValue0,...,typename KeyFromValuen>
>     struct composite_key;

>     template<typename CompositeKey>
>     struct composite_key_result;

>     // comparison operators for composite_key_result:

>     // OP is any of ==,<,!=,>,>=,<=

>     template<typename CompositeKey1,typename CompositeKey2>
>     bool operator OP(
>       const composite_key_result<CompositeKey1>& x,
>       const composite_key_result<CompositeKey2>& y);

>     template<typename CompositeKey,typename... Values>
>     bool operator OP(
>       const composite_key_result<CompositeKey>& x,
>       const std::tuple<Values...>& y);

>     template<typename CompositeKey,typename... Values>
>     bool operator OP(
>       const std::tuple<Values...>& x,
>       const composite_key_result<CompositeKey>& y);

>     template<typename CompositeKey,typename Value0,...,typename Valuen>
>     bool operator OP(
>       const composite_key_result<CompositeKey>& x,
>       const boost::tuple<Value0,...,Valuen>& y);

>     template<typename Value0,...,typename Valuen,typename CompositeKey>
>     bool operator OP(
>       const boost::tuple<Value0,...,Valuen>& x,
>       const composite_key_result<CompositeKey>& y);

>     // equality functors:

>     template<typename Pred0,...,typename Predn>
>     struct composite_key_equal_to;

>     template<typename CompositeKeyResult>
>     struct composite_key_result_equal_to; // deprecated

>     // comparison functors:

>     template<typename Compare0,...,typename Comparen>
>     struct composite_key_compare;

>     template<typename CompositeKeyResult>
>     struct composite_key_result_less;     // deprecated

>     template<typename CompositeKeyResult>
>     struct composite_key_result_greater;  // deprecated

>     // hash functors:

>     template<typename Hash0,...,typename Hashn>
>     struct composite_key_hash;

>     template<typename CompositeKeyResult>
>     struct composite_key_result_hash;     // deprecated

>     } // namespace boost::multi_index

>     } // namespace boost

>     // specializations of external functors for composite_key_result:

>     namespace std{

>     template<typename CompositeKey>
>     struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >;

>     template<typename CompositeKey>
>     struct less<boost::multi_index::composite_key_result<CompositeKey> >;

>     template<typename CompositeKey>
>     struct greater<boost::multi_index::composite_key_result<CompositeKey> >;

>     } // namespace std

>     namespace boost{

>     template<typename CompositeKey>
>     struct hash<boost::multi_index::composite_key_result<CompositeKey> >;

>     } // namespace boost

### Class template `composite_key`

`composite_key` is a `Key Extractor` returning the combined value of several key extractors whose type is specified at compile time. The returned object is of type `composite_key_result``<composite_key>`.

>     template<typename Value,typename KeyFromValue0,...,typename KeyFromValuen>
>     struct composite_key
>     {
>       typedef boost::tuple<KeyFromValue0,...,KeyFromValuen> key_extractor_tuple;
>       typedef Value                                         value_type;
>       typedef composite_key_result<composite_key>           result_type;

>       composite_key(
>         const KeyFromValue0& k0=KeyFromValue0(),
>         ...
>         const KeyFromValuen& kn=KeyFromValuen());

>       composite_key(const key_extractor_tuple& x);

>       const key_extractor_tuple& key_extractors()const;
>       key_extractor_tuple&       key_extractors()

>       // only provided if const ChainedPtr& is not convertible to const value_type&
>       template<typename ChainedPtr>
>       result_type operator()(const ChainedPtr& x)const;

>       result_type operator()(const value_type& x)const;
>       result_type operator()(const reference_wrapper<const value_type>& x)const;
>       result_type operator()(const reference_wrapper<value_type>& x)const;
>     };

`KeyFromValue0`, ... , `KeyFromValuen` are the types of the key extractors combined into the composite key. Each of these types must be a `Key Extractor` from `Value`. At least a key extractor must be provided. The maximum number of key extractors of a `composite_key` instantiation is implementation defined. `composite_key` internally stores an object of every constituent key extractor type. `composite_key<Value,KeyFromValue0,...,KeyFromValuen>` is a model of:

- `Key Extractor` from `Value`,
- `Key Extractor` from `reference_wrapper<const Value>`,
- `Key Extractor` from `reference_wrapper<Value>`,
- `Key Extractor` from any chained pointer to `const Value`,
- `Key Extractor` from any chained pointer to `Value`.

#### `composite_key` members

`composite_key(
const KeyFromValue0& k0=KeyFromValue0(),
...
const KeyFromValuen& kn=KeyFromValuen());`

> Effects: Constructs a `composite_key` that stores copies of the key extractor objects supplied.

`composite_key(const key_extractor_tuple& x);`

> Effects: Constructs a `composite_key` that stores copies of the key extractor objects supplied in `x`.

`const key_extractor_tuple& key_extractors()const;`

> Returns: a constant reference to a tuple holding the key extractors internally stored by the `composite_key`.

`key_extractor_tuple& key_extractors();`

> Returns: a reference to a tuple holding the key extractors internally stored by the `composite_key`.

`template<typename ChainedPtr>
result_type operator()(const ChainedPtr& x)const;`

> Requires: `ChainedPtr` is a chained pointer type to `result_type`.
> Returns: a `result_type` object dependent on `*this` and `y`, where `y` is the object chained-pointed to by `x`.

`result_type operator()(const value_type& x)const;`

> Returns: a `result_type` object dependent on `*this` and `x`.

`result_type operator()(const reference_wrapper<const value_type>& x)const;`

> Returns: a `result_type` object dependent on `*this` and `x.get()`.

`result_type operator()(const reference_wrapper<value_type>& x)const;`

> Returns: a `result_type` object dependent on `*this` and `x.get()`.

### Class template `composite_key_result`

This is an opaque type returned by `composite_key` instantiations as their extracted key.

>     template<typename CompositeKey>
>     struct composite_key_result
>     {
>       no public interface available
>     };

>     // comparison:

>     // OP is any of ==,<,!=,>,>=,<=

>     template<typename CompositeKey1,typename CompositeKey2>
>     bool operator OP(
>       const composite_key_result<CompositeKey1>& x,
>       const composite_key_result<CompositeKey2>& y);

>     template<typename CompositeKey,typename... Values>
>     bool operator OP(
>       const composite_key_result<CompositeKey>& x,
>       const std::tuple<Values...>& y);

>     template<typename CompositeKey,typename... Values>
>     bool operator OP(
>       const std::tuple<Values...>& x,
>       const composite_key_result<CompositeKey>& y);

>     template<typename CompositeKey,typename Value0,...,typename Valuen>
>     bool operator OP(
>       const composite_key_result<CompositeKey>& x,
>       const boost::tuple<Value0,...,Valuen>& y);

>     template<typename Value0,...,typename Valuen,typename CompositeKey>
>     bool operator OP(
>       const boost::tuple<Value0,...,Valuen>& x,
>       const composite_key_result<CompositeKey>& y);

`CompositeKey` is the `composite_key` instantiation to which the `composite_key_result` type is associated. Objects of type `composite_key_result` returned by a composite key must be always treated as temporary, i.e. they should not be stored or copied. `composite_key_result` is not guaranteed to be `DefaultConstructible` or `CopyAssignable`. Every object of type `composite_key_result<CompositeKey>` is internally associated to the `CompositeKey` from which it is returned and the object of type `CompositeKey::value_type` to which the composite key was applied.

#### Notation

Given an `x` of type `composite_key_result<CompositeKey>`, we use the following notation:

- `ck(x)` is the `CompositeKey` object associated to `x`,
- `v(x)` is the object of type `CompositeKey::value_type` associated to `x`,
- `ki(x) = ck(x).key_extractors().get<i>()`, that is, is the `i`-th key extractor of `ck(x)`,
- `xi = ki(x)(v(x))`, that is, the key extracted from `v(x)` by the `i`-th key extractor,
- `length(x)` is the number of key extractors of `ck(x)`.

Also, if `y` is an `std::tuple` or `boost::tuple` of values, we define:

- `yi=get<i>(y)`,
- `length(y)` is the number of elements of `y`.

#### Comparison operators

`template<typename CompositeKey1,typename CompositeKey2>
bool operator==(
const composite_key_result<CompositeKey1>& x,
const composite_key_result<CompositeKey2>& y);
template<typename CompositeKey,typename... Values>
bool operator==(
const composite_key_result<CompositeKey>& x,
const std::tuple<Values...>& y);
template<typename CompositeKey,typename... Values>
bool operator==(
const std::tuple<Values...>& x,
const composite_key_result<CompositeKey>& y);
template<typename CompositeKey,typename Value0,...,typename Valuen>
bool operator==(
const composite_key_result<CompositeKey>& x,
const boost::tuple<Value0,...,Valuen>& y);
template<typename Value0,...,typename Valuen,typename CompositeKey>
bool operator==(
const boost::tuple<Value0,...,Valuen>& x,
const composite_key_result<CompositeKey>& y);`

> Requires: `length(x)==length(y)`. The expression `xi==yi` is valid for all `i` in `[0,length(x))`.
> Returns: `true` if and only if

> > `xi==yi` for all `i` in `[0,length(x))`.

> Complexity: No more key extraction operations and comparisons are performed than those necessary for the evaluation of the expression above, starting at `i==0`. The evaluation is short-circuited as soon as the result is determined to be `false`.

`template<typename CompositeKey1,typename CompositeKey2>
bool operator<(
const composite_key_result<CompositeKey1>& x,
const composite_key_result<CompositeKey2>& y);
template<typename CompositeKey,typename... Values>
bool operator<(
const composite_key_result<CompositeKey>& x,
const std::tuple<Values...>& y);
template<typename CompositeKey,typename... Values>
bool operator<(
const std::tuple<Values...>& x,
const composite_key_result<CompositeKey>& y);
template<typename CompositeKey,typename Value0,...,typename Valuen>
bool operator<(
const composite_key_result<CompositeKey>& x,
const boost::tuple<Value0,...,Valuen>& y);
template<typename Value0,...,typename Valuen,typename CompositeKey>
bool operator<(
const boost::tuple<Value0,...,Valuen>& x,
const composite_key_result<CompositeKey>& y);`

> Requires: The expressions `xi<yi` and `yi<xi` are valid for all `i` in `[0,min(length(x),length(y)))`.
> Returns: `true` if and only if there exists some `j` in the range `[0,min(length(x),length(y)))` such that

> > `!(xi<yi) && !(yi<xi)` for all `i` in `[0,j)`,
> > `xj<yj`.

> Complexity: No more key extraction operations and comparisons are performed than those necessary for the evaluation of the expression above, starting at `i==0`. The evaluation is short-circuited as soon as the result is determined to be `false`.

`template<typename CompositeKey1,typename CompositeKey2>
bool operator OP(
const composite_key_result<CompositeKey1>& x,
const composite_key_result<CompositeKey2>& y);
template<typename CompositeKey,typename... Values>
bool operator OP(
const composite_key_result<CompositeKey>& x,
const std::tuple<Values...>& y);
template<typename CompositeKey,typename... Values>
bool operator OP(
const std::tuple<Values...>& x,
const composite_key_result<CompositeKey>& y);
template<typename CompositeKey,typename Value0,...,typename Valuen>
bool operator OP(
const composite_key_result<CompositeKey>& x,
const boost::tuple<Value0,...,Valuen>& y);
template<typename Value0,...,typename Valuen,typename CompositeKey>
bool operator OP(
const boost::tuple<Value0,...,Valuen>& x,
const composite_key_result<CompositeKey>& y);`

(`OP` is any of `!=`, `>`, `>=`, `<=`.)

> Requires: The expressions given below are valid (for the particular `OP` considered.)
> Returns: `true` if and only if

> > `!(x==y)` (`OP` is `!=`),
> > `y< x` (`OP` is `>` ),
> > `!(x< y)` (`OP` is `>=`),
> > `!(y< x)` (`OP` is `<=`).

### Equality

#### Class template `composite_key_equal_to`

`composite_key_equal_to` tests for equality between `composite_key_result` instantiations and between these and tuples of values, using an internally stored collection of elementary equality predicates.

>     template<typename Pred0,...,typename Predn>
>     struct composite_key_equal_to
>     {
>       typedef boost::tuple<Pred0,...,Predn> key_eq_tuple;

>       composite_key_equal_to(
>         const Pred0& p0=Pred0(),
>         ...
>         const Predn& pn=Predn());

>       composite_key_equal_to(const key_eq_tuple& x);

>       const key_eq_tuple& key_eqs()const;
>       key_eq_tuple&       key_eqs();

>       template<typename CompositeKey1,typename CompositeKey2>
>       bool operator()(
>         const composite_key_result<CompositeKey1> & x,
>         const composite_key_result<CompositeKey2> & y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const composite_key_result<CompositeKey>& x,
>         const std::tuple<Values...>& y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const std::tuple<Values...>& x,
>         const composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value0,...,typename Valuen>
>       bool operator()(
>         const composite_key_result<CompositeKey>& x,
>         const boost::tuple<Value0,...,Valuen>& y)const;

>       template<typename Value0,...,typename Valuen,typename CompositeKey>
>       bool operator()(
>         const boost::tuple<Value0,...,Valuen>& x,
>         const composite_key_result<CompositeKey>& y)const;
>     };

`Pred0`, ... , `Predn` are the types of the equality binary predicates stored by `composite_key_equal_to`. Each of these predicates must be `CopyConstructible` and `CopyAssignable`. At least an equality predicate must be provided. The maximum number of equality predicates of a `composite_key_equal_to` instantiation is implementation defined. `composite_key_equal_to` is `CopyConstructible` and `CopyAssignable`. It is also `DefaultConstructible` if each `Predi` is `DefaultConstructible` in its turn.

Note that formally it is not required that the `Predi` types behave as equality predicates in any definite way. However, the semantics of `composite_key_equal_to` is well defined if this is the case, as explained in the section on the semantics of `composite_key_result`.

#### Notation

In what follows we use the same notation introduced for `composite_key_result`.

#### `composite_key_equal_to` members

`composite_key_equal_to(
const Pred0& p0=Pred0(),
...
const Predn& pn=Predn());`

> Effects: Constructs a `composite_key_equal_to` that stores copies of the equality predicates supplied.

`composite_key_equal_to(const key_eq_tuple& x);`

> Effects: Constructs a `composite_key_equal_to` that stores copies of the equality predicate objects supplied in `x`.

`const key_eq_tuple& key_eqs()const;`

> Returns: a constant reference to a tuple holding the equality predicate objects internally stored by the `composite_key_equal_to`.

`key_eq_tuple& key_eqs();`

> Returns: a reference to a tuple holding the equality predicate objects internally stored by the `composite_key_equal_to`.

`template<typename CompositeKey1,typename CompositeKey2>
bool operator()(
const composite_key_result<CompositeKey1> & x,
const composite_key_result<CompositeKey2> & y)const;
template<typename CompositeKey,typename Values...>
bool operator()(
const composite_key_result<CompositeKey>& x,
const std::tuple<Values...>& y)const;
template<typename CompositeKey,typename Values...>
bool operator()(
const std::tuple<Values...>& x,
const composite_key_result<CompositeKey>& y)const;
template<typename CompositeKey,typename Value0,...,typename Valuen>
bool operator()(
const composite_key_result<CompositeKey>& x,
const boost::tuple<Value0,...,Valuen>& y)const;
template<typename Value0,...,typename Valuen,typename CompositeKey>
bool operator()(
const boost::tuple<Value0,...,Valuen>& x,
const composite_key_result<CompositeKey>& y)const;
`

> Requires: `length(x)==length(y)`. The expressions `key_eqs().get<i>()(xi,yi)` and `key_eqs().get<i>()(yi,xi)` are valid for all `i` in `[0,length(x))`.
> Returns: `true` if and only

> > `key_eqs().get<i>()(xi,yi)` for all `i` in `[0,length(x))`.

> Complexity: No more key extraction operations and comparisons are performed than those necessary for the evaluation of the expression above, starting at `i==0`. The evaluation is short-circuited as soon as the result is determined to be `false`.

#### Class template `composite_key_result_equal_to`

Deprecated. Use `std::equal_to<CompositeKeyResult>` instead.

#### Specialization of `std::equal_to` for `composite_key` results

`std::equal_to<CompositeKeyResult>`, with `CompositeKeyResult` an instantiation of `composite_key_result`, behaves as a particularization of `composite_key_equal_to` where all the comparison predicates supplied are instantiations of `std::equal_to`.

>     namespace std{

>     template<typename CompositeKey>
>     struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >
>     {
>       typedef
>         boost::multi_index::composite_key_result<
>           CompositeKey>                           first_argument_type;
>       typedef first_argument_type                 second_argument_type;
>       typedef bool                                result_type;

>       template<typename CompositeKey1,typename CompositeKey2>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey1> & x,
>         const boost::multi_index::composite_key_result<CompositeKey2> & y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const std::tuple<Values...>& y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const std::tuple<Values...>& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value0,...,typename Valuen>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const boost::tuple<Value0,...,Valuen>& y)const;

>       template<typename Value0,...,typename Valuen,typename CompositeKey>
>       bool operator()(
>         const boost::tuple<Value0,...,Valuen>& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;
>     };

>     } // namespace std

`CompositeKeyResult` must be an instantiation of `composite_key_result` for some type `composite_key<KeyFromValue0,...,KeyFromValuen>`. `std::equal_to<CompositeKeyResult>::operator()` is then equivalent to `composite_key_equal_to<Pred0,...,Predn>::operator()`, taking

> `Predi = std::equal_to<KeyFromValuei::result_type>` for all `i = 0,...,n`.

In addition to the requirements on `Predi` imposed by `composite_key_equal_to`, each of these types must be `DefaultConstructible`. `std::equal_to<CompositeKeyResult>` is `DefaultConstructible`, `CopyConstructible` and `CopyAssignable`.

### Comparison

#### Class template `composite_key_compare`

`composite_key_compare` compares `composite_key_result` instantiations between them and with tuples of values using an internally stored collection of elementary comparison predicates.

>     template<typename Compare0,...,typename Comparen>
>     struct composite_key_compare
>     {
>       typedef boost::tuple<Compare0,...,Comparen> key_comp_tuple;

>       composite_key_compare(
>         const Compare0& c0=Compare0(),
>         ...
>         const Comparen& cn=Comparen());

>       composite_key_compare(const key_comp_tuple& x);

>       const key_comp_tuple& key_comps()const;
>       key_comp_tuple&       key_comps();

>       template<typename CompositeKey1,typename CompositeKey2>
>       bool operator()(
>         const composite_key_result<CompositeKey1> & x,
>         const composite_key_result<CompositeKey2> & y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const composite_key_result<CompositeKey>& x,
>         const std::tuple<Values...>& y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const std::tuple<Values...>& x,
>         const composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value0,...,typename Valuen>
>       bool operator()(
>         const composite_key_result<CompositeKey>& x,
>         const boost::tuple<Value0,...,Valuen>& y)const;

>       template<typename Value0,...,typename Valuen,typename CompositeKey>
>       bool operator()(
>         const boost::tuple<Value0,...,Valuen>& x,
>         const composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value>
>       bool operator()(
>         const composite_key_result<CompositeKey>& x,const Value& y)const;

>       template<typename Value,typename CompositeKey>
>       bool operator()(
>         const Value& x,const composite_key_result<CompositeKey>& y)const;
>     };

`Compare0`, ... , `Comparen` are the types of the comparison binary predicates stored by `composite_key_compare`. Each of these predicates must be `CopyConstructible` and `CopyAssignable`. At least a comparison predicate must be provided. The maximum number of comparison predicates of a `composite_key_compare` instantiation is implementation defined. `composite_key_compare` is `CopyConstructible` and `CopyAssignable`. It is also `DefaultConstructible` if each `Comparei` is `DefaultConstructible` in its turn.

Note that formally it is not required that the `Comparei` types behave as comparison predicates in any definite way. However, the semantics of `composite_key_compare` is well defined if this is the case, as explained in the section on the semantics of `composite_key_result`.

#### Notation

In what follows we use the same notation introduced for `composite_key_result`.

#### `composite_key_compare` members

`composite_key_compare(
const Compare0& c0=Compare0(),
...
const Comparen& cn=Comparen());`

> Effects: Constructs a `composite_key_compare` that stores copies of the comparison predicates supplied.

`composite_key_compare(const key_comp_tuple& x);`

> Effects: Constructs a `composite_key_compare` that stores copies of the comparison predicate objects supplied in `x`.

`const key_comp_tuple& key_comps()const;`

> Returns: a constant reference to a tuple holding the comparison predicate objects internally stored by the `composite_key_compare`.

`key_comp_tuple& key_comps();`

> Returns: a reference to a tuple holding the comparison predicate objects internally stored by the `composite_key_compare`.

`template<typename CompositeKey1,typename CompositeKey2>
bool operator()(
const composite_key_result<CompositeKey1> & x,
const composite_key_result<CompositeKey2> & y)const;
template<typename CompositeKey,typename... Values>
bool operator()(
const composite_key_result<CompositeKey>& x,
const std::tuple<Values...>& y)const;
template<typename CompositeKey,typename... Values>
bool operator()(
const std::tuple<Values...>& x,
const composite_key_result<CompositeKey>& y)const;
template<typename CompositeKey,typename Value0,...,typename Valuen>
bool operator()(
const composite_key_result<CompositeKey>& x,
const boost::tuple<Value0,...,Valuen>& y)const;
template<typename Value0,...,typename Valuen,typename CompositeKey>
bool operator()(
const boost::tuple<Value0,...,Valuen>& x,
const composite_key_result<CompositeKey>& y)const;
`

> Requires: The expressions `key_comps().get<i>()(xi,yi)` and `key_comps().get<i>()(yi,xi)` are valid for all `i` in `[0,min(length(x),length(y)))`.
> Returns: `true` if and only if there exists some `j` in the range `[0,min(length(x),length(y)))` such that

> > `!key_comps().get<i>()(xi,yi) && !key_comps().get<i>()(yi,xi)` for all `i` in `[0,j)`,
> > `key_comps().get<j>()(xj,yj)`.

> Complexity: No more key extraction operations and comparisons are performed than those necessary for the evaluation of the expression above, starting at `i==0`. The evaluation is short-circuited as soon as the result is determined to be `false`.

`template<typename CompositeKey,typename Value>
bool operator()(
const composite_key_result<CompositeKey>& x,const Value& y)const;`

> Effects:

> >     return operator()(x,boost::make_tuple(boost::cref(y)));

`template<typename Value,typename CompositeKey>
bool operator()(
const Value& x,const composite_key_result<CompositeKey>& y)const;`

> Effects:

> >     return operator()(boost::make_tuple(boost::cref(x)),y);

#### Class template `composite_key_result_less`

Deprecated. Use `std::less<CompositeKeyResult>` instead.

#### Class template `composite_key_result_greater`

Deprecated. Use `std::greater<CompositeKeyResult>` instead.

#### Specialization of `std::less` for `composite_key` results

`std::less<CompositeKeyResult>`, with `CompositeKeyResult` an instantiation of `composite_key_result`, behaves as a particularization of `composite_key_compare` where all the comparison predicates supplied are instantiations of `std::less`.

>     namespace std{

>     template<typename CompositeKey>
>     struct less<boost::multi_index::composite_key_result<CompositeKey> >
>     {
>       typedef
>         boost::multi_index::composite_key_result<
>           CompositeKey>                           first_argument_type;
>       typedef first_argument_type                 second_argument_type;
>       typedef bool                                result_type;

>       template<typename CompositeKey1,typename CompositeKey2>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey1> & x,
>         const boost::multi_index::composite_key_result<CompositeKey2> & y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const std::tuple<Values...>& y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const std::tuple<Values...>& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value0,...,typename Valuen>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const boost::tuple<Value0,...,Valuen>& y)const;

>       template<typename Value0,...,typename Valuen,typename CompositeKey>
>       bool operator()(
>         const boost::tuple<Value0,...,Valuen>& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const Value& y)const;

>       template<typename Value,typename CompositeKey>
>       bool operator()(
>         const Value& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;
>     };

>     } // namespace std

`CompositeKeyResult` must be an instantiation of `composite_key_result` for some type `composite_key<KeyFromValue0,...,KeyFromValuen>`. `std::less<CompositeKeyResult>::operator()` is then equivalent to `composite_key_compare<Compare0,...,Comparen>::operator()`, taking

> `Comparei = std::less<KeyFromValuei::result_type>` for all `i = 0,...,n`.

In addition to the requirements on `Comparei` imposed by `composite_key_compare`, each of these types must be `DefaultConstructible`. `std::less<CompositeKeyResult>` is `DefaultConstructible`, `CopyConstructible` and `CopyAssignable`.

#### Specialization of `std::greater` for `composite_key` results

`std::greater<CompositeKeyResult>`, with `CompositeKeyResult` an instantiation of `composite_key_result`, behaves as a particularization of `composite_key_compare` where all the comparison predicates supplied are instantiations of `std::greater`.

>     namespace std{

>     template<typename CompositeKey>
>     struct greater<boost::multi_index::composite_key_result<CompositeKey> >
>     {
>       typedef
>         boost::multi_index::composite_key_result<
>           CompositeKey>                           first_argument_type;
>       typedef first_argument_type                 second_argument_type;
>       typedef bool                                result_type;

>       template<typename CompositeKey1,typename CompositeKey2>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey1> & x,
>         const boost::multi_index::composite_key_result<CompositeKey2> & y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const std::tuple<Values...>& y)const;

>       template<typename CompositeKey,typename... Values>
>       bool operator()(
>         const std::tuple<Values...>& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value0,...,typename Valuen>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const boost::tuple<Value0,...,Valuen>& y)const;

>       template<typename Value0,...,typename Valuen,typename CompositeKey>
>       bool operator()(
>         const boost::tuple<Value0,...,Valuen>& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;

>       template<typename CompositeKey,typename Value>
>       bool operator()(
>         const boost::multi_index::composite_key_result<CompositeKey>& x,
>         const Value& y)const;

>       template<typename Value,typename CompositeKey>
>       bool operator()(
>         const Value& x,
>         const boost::multi_index::composite_key_result<CompositeKey>& y)const;
>     };

>     } // namespace std

`CompositeKeyResult` must be an instantiation of `composite_key_result` for some type `composite_key<KeyFromValue0,...,KeyFromValuen>`. `std::greater<CompositeKeyResult>::operator()` is then equivalent to `composite_key_compare<Compare0,...,Comparen>::operator()`, taking

> `Comparei = std::greater<KeyFromValuei::result_type>` for all `i = 0,...,n`.

In addition to the requirements on `Comparei` imposed by `composite_key_compare`, each of these types must be `DefaultConstructible`. `std::greater<CompositeKeyResult>` is `DefaultConstructible`, `CopyConstructible` and `CopyAssignable`.

### Hashing

#### Class template `composite_key_hash`

`composite_key_hash` produces hash values for `composite_key_result` instantiations based on a collection of elementary hash functors.

>     template<typename Hash0,...,typename Hashn>
>     struct composite_key_hash
>     {
>       typedef boost::tuple<Hash0,...,Hashn> key_hasher_tuple;

>       composite_key_hash(
>         const Hash0& h0=Hash0(),
>         ...
>         const Hashn& hn=Hashn());

>       composite_key_hash(const key_hasher_tuple& x);

>       const key_hasher_tuple& key_hash_functions()const;
>       key_hasher_tuple&       key_hash_functions();

>       template<typename CompositeKey>
>       std::size_t operator()(
>         const composite_key_result<CompositeKey>& x)const;

>       template<typename... Values>
>       std::size_t operator()(
>         const std::tuple<Values...>& x)const;

>       template<typename Value0,...,typename Valuen>
>       std::size_t operator()(
>         const boost::tuple<Value0,...,Valuen>& x)const;
>     };

`Hash0`, ... , `Hashn` are the types of the hash unary function objects stored by `composite_key_hash`. Each of these objects must be `CopyConstructible` and `CopyAssignable` and return a value of type `std::size_t` in the range [0, `std::numeric_limits<std::size_t>::max())`). At least a hash functor must be provided. The maximum number of hash functors of a `composite_key_hash` instantiation is implementation defined. `composite_key_hash` is `CopyConstructible` and `CopyAssignable`. It is also `DefaultConstructible` if each `Hashi` is `DefaultConstructible` in its turn.

#### Notation

In what follows we use the same notation introduced for `composite_key_result`.

#### `composite_key_hash` members

`composite_key_hash(
const Hash0& h0=Hash0(),
...
const Hashn& hn=Hashn());`

> Effects: Constructs a `composite_key_hash` that stores copies of the hash functors supplied.

`composite_key_hash(const key_hasher_tuple& x);`

> Effects: Constructs a `composite_key_hash` that stores copies of the hash functors supplied in `x`.

`const key_hasher_tuple& key_hash_functions()const;`

> Returns: a constant reference to a tuple holding the hash functors internally stored by the `composite_key_hash`.

`key_hasher_tuple& key_hash_functions();`

> Returns: a reference to a tuple holding the hash functors internally stored by the `composite_key_hash`.

`template<typename CompositeKey>
bool operator()(
const composite_key_result<CompositeKey>& x)const;
template<typename... Values>
bool operator()(
const std::tuple<Values...>& x)const;
template<typename Value0,...,typename Valuen>
bool operator()(
const boost::tuple<Value0,...,Valuen>& x)const;`

> Requires: `length(x)==length(key_hash_functions())`. The expression `key_hash_functions().get<i>()(xi)` is valid for all `i` in `[0,length(x))`.
> Returns: A value in the range `[0, std::numeric_limits<std::size_t>::max())` that solely depends on the numerical tuple

> > (`key_hash_functions().get<0>()(x0)`, ... , `key_hash_functions().get<N>()(xN)`), with `N=length(x)-1`.

#### Class template `composite_key_result_hash`

Deprecated. Use `boost::hash<CompositeKeyResult>` instead.

#### Specialization of `boost::hash` for `composite_key` results

`boost::hash<CompositeKeyResult>`, with `CompositeKeyResult` an instantiation of `composite_key_result`, behaves as a particularization of `composite_key_hash` where all the hash functors supplied are instantiations of `boost::hash`.

>     namespace boost{

>     template<typename CompositeKey>
>     struct hash<multi_index::composite_key_result<CompositeKey> >
>     {
>       typedef multi_index::composite_key_result<CompositeKey> argument_type;
>       typedef std::size_t                                     result_type;

>       template<typename CompositeKey>
>       std::size_t operator()(
>         const multi_index::composite_key_result<CompositeKey>& x)const;

>       template<typename... Values>
>       std::size_t operator()(
>         const std::tuple<Values...>& x)const;

>       template<typename Value0,...,typename Valuen>
>       std::size_t operator()(
>         const boost::tuple<Value0,...,Valuen>& x)const;
>     };

>     } // namespace boost

`CompositeKeyResult` must be an instantiation of `composite_key_result` for some type `composite_key<KeyFromValue0,...,KeyFromValuen>`. `boost::hash<CompositeKeyResult>::operator()` is then equivalent to `composite_key_hash<Hash0,...,Hashn>::operator()`, taking

> `Hashi = boost::hash<KeyFromValuei::result_type>` for all `i = 0,...,n`.

In addition to the requirements on `Hashi` imposed by `composite_key_hash`, each of these types must be `DefaultConstructible`. `boost::hash<CompositeKeyResult>` is `DefaultConstructible`, `CopyConstructible` and `CopyAssignable`.

### Semantics of `composite_key_result`

The design of equality, comparison and hash operations for `composite_key_result` objects is based on the following rationale: a `composite_key_result` is regarded as a "virtual" tuple, each of its elements being the result of the corresponding elementary key extractor. Accordingly, any given operation resolves to a combination of the corresponding elementwise operations. This mapping preserves the fundamental properties of the elementary operations involved; for instance, it defines a true equivalence relation if the basic predicates induce equivalence relations themselves. We can state these facts in a formal way as follows.

Consider an instantiation of `composite_key_equal_to` with types `Pred0`, ... , `Predn` such that each `Predi` induces an equivalence relation on a certain type `Ti`, and let `CompositeKey` be a type of the form `composite_key<Value,KeyFromValue0,...,KeyFromValuej>`, with `j <= n`, such that

> `KeyFromValuei::result_type = Ti`, for all `i = 0,...,j`.

Then, `composite_key_equal_to` induces an equivalence relation on elements of type `composite_key_result<CompositeKey>`; such two objects are equivalent if all its elementary key extractor values are also equivalent. Additionally, given an instantiation `composite_key_hash<Hash0,...,Hashj>`, the following types are `Compatible Keys` of (`composite_key_hash`, `composite_key_equal_to`) with respect to `composite_key_result<CompositeKey>`:

> `tuple<Q0,...,Qj>`,
> `composite_key_result<composite_key<K0,...,Kj> >`, with `Ki::result_type = Qi` for all `i = 0,...,j`.

provided that each `Qi` is either `Ti` or a `Compatible Key` of (`Hashi`, `Predi`).

As for comparison, consider an instantiation of `composite_key_compare` with types `Compare0`, ... , `Comparen` such that each `Comparei` induces a strict weak ordering on the type `Ti`. Then, for a `CompositeKey` type defined in the same manner as above, `composite_key_compare` induces a strict weak ordering on elements of type `composite_key_result<CompositeKey>`, and the order induced is lexicographical. Also, the following types are `Compatible Keys` of `composite_key_compare` with respect to `composite_key_result<CompositeKey>`:

> `tuple<Q0,...,Qk>`, `k <= n`
> `composite_key_result<composite_key<K0,...,Kk> >`, with `Ki::result_type = Qi` for all `i = 0,...,k`.

provided that

- for `i = 0,...,min(j,k)-1`, `Qi` is either `Ti` or not coarser than `Ti` (`Qi` is a `Compatible Key` of `Comparei` and there are no two distinct elements of `Ti` equivalent to one single element of `Qi`);
- `Qm` (with `m = min(j,k)`) is either `Tm` or a `Compatible Key` of `Comparem`.

In this case, the comparison is done lexicographically only on the first `1+min(j,k)` elements.

Analogous properties hold for the equality and comparison operators of `composite_key_result`. Note, however, that equality is only defined for objects of the same length, whilst comparison takes the minimum length of the operands considered. Therefore, the equivalence classes induced by `x==y` are subsets of those associated to `!(x<y)&&!(y<x)`.

## Header `"boost/multi_index/key.hpp"` synopsis

>     #include <boost/multi_index/member.hpp>
>     #include <boost/multi_index/mem_fun.hpp>
>     #include <boost/multi_index/global_fun.hpp>
>     #include <boost/multi_index/composite_key.hpp>

>     #if implementation defined /* auto non-type template parameters supported */

>     #define BOOST_MULTI_INDEX_KEY_SUPPORTED

>     namespace boost{

>     namespace multi_index{

>     template<auto... Keys>
>     using key=implementation defined;

>     } /* namespace multi_index */

>     } /* namespace boost */

>     #endif

### Alias template `key`

In C++17 compliant environments, `key` provides a very terse syntax for the specification of Boost.MultiIndex predefined key extractors. The number of template arguments passed to `key` must be greater than zero and not exceed the maximum number of key extractors accepted by `composite_key`. `key<Key>` resolves to:

- `member<Class,Type,Key>` if `Key` is of type `Type Class::*`,
- `const_mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()const` (with or without `noexcept`-specification),
- `cv_mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()const volatile` (with or without `noexcept`-specification),
- `cref_mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()const&` (with or without `noexcept`-specification),
- `cvref_mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()const volatile&` (with or without `noexcept`-specification),
- `mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()` (with or without `noexcept`-specification),
- `volatile_mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()volatile` (with or without `noexcept`-specification),
- `ref_mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()&` (with or without `noexcept`-specification),
- `vref_mem_fun<Class,Type,Key>` if `Key` is of type `Type (Class::*)()volatile&` (with or without `noexcept`-specification),
- `global_fun<Value,Type,Key>` if `Key` is of type `Type (*)(Value)` (with or without `noexcept`-specification),

and engenders undefined behavior otherwise. When passed two or more arguments, `key<Key0,...,Keyn>` resolves to `composite_key<Value,KeyFromValue0,...,KeyFromValuen>`, with:

- `KeyFromValuei` = `key<Keyi>` for all `i = 0,...,n`
- `Value` = `std::decay_t<Value0>` ⊗ `std::decay_t<Value1>` ⊗ ··· ⊗ `std::decay_t<Valuen>`,

where `Valuei` corresponds to the associated `Class` or `Value` type of `KeyFromValuei`, and `T` ⊗ `Q` is the least generic type between `T` and `Q`, defined as `T` if `std::is_convertible_v<const T&,const Q&>`, `Q` if `std::is_convertible_v<const Q&,const T&>`, and undefined otherwise.

Random access indices
Boost.MultiIndex reference
Compiler specifics

Revised April 19th 2020

© Copyright 2003-2020 Joaquín M López Muñoz. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)