source: NonGTP/Boost/boost/multi_index/identity.hpp @ 857

Revision 857, 3.1 KB checked in by igarcia, 19 years ago (diff)
RevLine 
[857]1/* Copyright 2003-2005 Joaquín M López Muñoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/multi_index for library home page.
7 */
8
9#ifndef BOOST_MULTI_INDEX_IDENTITY_HPP
10#define BOOST_MULTI_INDEX_IDENTITY_HPP
11
12#if defined(_MSC_VER)&&(_MSC_VER>=1200)
13#pragma once
14#endif
15
16#include <boost/config.hpp>
17#include <boost/mpl/if.hpp>
18#include <boost/multi_index/identity_fwd.hpp>
19#include <boost/type_traits/is_const.hpp>
20#include <boost/type_traits/remove_const.hpp>
21
22namespace boost{
23
24template<class Type> class reference_wrapper; /* fwd decl. */
25
26namespace multi_index{
27
28namespace detail{
29
30/* identity is a do-nothing key extractor that returns the [const] Type&
31 * object passed.
32 * Additionally, identity is overloaded to support referece_wrappers
33 * of Type and "chained pointers" to Type's. By chained pointer to Type we
34 * mean a  type  P such that, given a p of type P
35 *   *...n...*x is convertible to Type&, for some n>=1.
36 * Examples of chained pointers are raw and smart pointers, iterators and
37 * arbitrary combinations of these (vg. Type** or auto_ptr<Type*>.)
38 */
39
40/* NB. Some overloads of operator() have an extra dummy parameter int=0.
41 * This disambiguator serves several purposes:
42 *  - Without it, MSVC++ 6.0 incorrectly regards some overloads as
43 *    specializations of a previous member function template.
44 *  - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
45 *    as if they have the same signature.
46 *  - If remove_const is broken due to lack of PTS, int=0 avoids the
47 *    declaration of memfuns with identical signature.
48 */
49
50template<typename Type>
51struct const_identity_base
52{
53  typedef Type result_type;
54
55  template<typename ChainedPtr>
56  Type& operator()(const ChainedPtr& x)const
57  {
58    return operator()(*x);
59  }
60
61  Type& operator()(Type& x)const
62  {
63    return x;
64  }
65
66  Type& operator()(const reference_wrapper<Type>& x)const
67  {
68    return x.get();
69  }
70
71  Type& operator()(
72    const reference_wrapper<typename remove_const<Type>::type>& x,int=0)const
73  {
74    return x.get();
75  }
76};
77
78template<typename Type>
79struct non_const_identity_base
80{
81  typedef Type result_type;
82
83  /* templatized for pointer-like types */
84 
85  template<typename ChainedPtr>
86  Type& operator()(const ChainedPtr& x)const
87  {
88    return operator()(*x);
89  }
90
91  const Type& operator()(const Type& x,int=0)const
92  {
93    return x;
94  }
95
96  Type& operator()(Type& x)const
97  {
98    return x;
99  }
100
101  const Type& operator()(const reference_wrapper<const Type>& x,int=0)const
102  {
103    return x.get();
104  }
105
106  Type& operator()(const reference_wrapper<Type>& x)const
107  {
108    return x.get();
109  }
110};
111
112} /* namespace multi_index::detail */
113
114template<class Type>
115struct identity:
116  mpl::if_c<
117    is_const<Type>::value,
118    detail::const_identity_base<Type>,detail::non_const_identity_base<Type>
119  >::type
120{
121};
122
123} /* namespace multi_index */
124
125} /* namespace boost */
126
127#endif
Note: See TracBrowser for help on using the repository browser.