Chris@16
|
1 /* Copyright 2003-2008 Joaquin M Lopez Munoz.
|
Chris@16
|
2 * Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
3 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 *
|
Chris@16
|
6 * See http://www.boost.org/libs/multi_index for library home page.
|
Chris@16
|
7 */
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_MULTI_INDEX_GLOBAL_FUN_HPP
|
Chris@16
|
10 #define BOOST_MULTI_INDEX_GLOBAL_FUN_HPP
|
Chris@16
|
11
|
Chris@16
|
12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
Chris@16
|
13 #pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
Chris@16
|
17 #include <boost/mpl/if.hpp>
|
Chris@16
|
18 #include <boost/type_traits/is_const.hpp>
|
Chris@16
|
19 #include <boost/type_traits/is_reference.hpp>
|
Chris@16
|
20 #include <boost/type_traits/remove_const.hpp>
|
Chris@16
|
21 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
22 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #if !defined(BOOST_NO_SFINAE)
|
Chris@16
|
25 #include <boost/type_traits/is_convertible.hpp>
|
Chris@16
|
26 #endif
|
Chris@16
|
27
|
Chris@16
|
28 namespace boost{
|
Chris@16
|
29
|
Chris@16
|
30 template<class T> class reference_wrapper; /* fwd decl. */
|
Chris@16
|
31
|
Chris@16
|
32 namespace multi_index{
|
Chris@16
|
33
|
Chris@16
|
34 namespace detail{
|
Chris@16
|
35
|
Chris@16
|
36 /* global_fun is a read-only key extractor from Value based on a given global
|
Chris@16
|
37 * (or static member) function with signature:
|
Chris@16
|
38 *
|
Chris@16
|
39 * Type f([const] Value [&]);
|
Chris@16
|
40 *
|
Chris@16
|
41 * Additionally, global_fun and const_global_fun are overloaded to support
|
Chris@16
|
42 * referece_wrappers of Value and "chained pointers" to Value's. By chained
|
Chris@16
|
43 * pointer to T we mean a type P such that, given a p of Type P
|
Chris@16
|
44 * *...n...*x is convertible to T&, for some n>=1.
|
Chris@16
|
45 * Examples of chained pointers are raw and smart pointers, iterators and
|
Chris@16
|
46 * arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
|
Chris@16
|
47 */
|
Chris@16
|
48
|
Chris@16
|
49 /* NB. Some overloads of operator() have an extra dummy parameter int=0.
|
Chris@16
|
50 * This disambiguator serves several purposes:
|
Chris@16
|
51 * - Without it, MSVC++ 6.0 incorrectly regards some overloads as
|
Chris@16
|
52 * specializations of a previous member function template.
|
Chris@16
|
53 * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
|
Chris@16
|
54 * as if they have the same signature.
|
Chris@16
|
55 * - If remove_const is broken due to lack of PTS, int=0 avoids the
|
Chris@16
|
56 * declaration of memfuns with identical signature.
|
Chris@16
|
57 */
|
Chris@16
|
58
|
Chris@16
|
59 template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
Chris@16
|
60 struct const_ref_global_fun_base
|
Chris@16
|
61 {
|
Chris@16
|
62 typedef typename remove_reference<Type>::type result_type;
|
Chris@16
|
63
|
Chris@16
|
64 template<typename ChainedPtr>
|
Chris@16
|
65
|
Chris@16
|
66 #if !defined(BOOST_NO_SFINAE)
|
Chris@16
|
67 typename disable_if<
|
Chris@16
|
68 is_convertible<const ChainedPtr&,Value>,Type>::type
|
Chris@16
|
69 #else
|
Chris@16
|
70 Type
|
Chris@16
|
71 #endif
|
Chris@16
|
72
|
Chris@16
|
73 operator()(const ChainedPtr& x)const
|
Chris@16
|
74 {
|
Chris@16
|
75 return operator()(*x);
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 Type operator()(Value x)const
|
Chris@16
|
79 {
|
Chris@16
|
80 return PtrToFunction(x);
|
Chris@16
|
81 }
|
Chris@16
|
82
|
Chris@16
|
83 Type operator()(
|
Chris@16
|
84 const reference_wrapper<
|
Chris@16
|
85 typename remove_reference<Value>::type>& x)const
|
Chris@16
|
86 {
|
Chris@16
|
87 return operator()(x.get());
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@16
|
90 Type operator()(
|
Chris@16
|
91 const reference_wrapper<
|
Chris@16
|
92 typename remove_const<
|
Chris@16
|
93 typename remove_reference<Value>::type>::type>& x,int=0)const
|
Chris@16
|
94 {
|
Chris@16
|
95 return operator()(x.get());
|
Chris@16
|
96 }
|
Chris@16
|
97 };
|
Chris@16
|
98
|
Chris@16
|
99 template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
Chris@16
|
100 struct non_const_ref_global_fun_base
|
Chris@16
|
101 {
|
Chris@16
|
102 typedef typename remove_reference<Type>::type result_type;
|
Chris@16
|
103
|
Chris@16
|
104 template<typename ChainedPtr>
|
Chris@16
|
105
|
Chris@16
|
106 #if !defined(BOOST_NO_SFINAE)
|
Chris@16
|
107 typename disable_if<
|
Chris@16
|
108 is_convertible<ChainedPtr&,Value>,Type>::type
|
Chris@16
|
109 #else
|
Chris@16
|
110 Type
|
Chris@16
|
111 #endif
|
Chris@16
|
112
|
Chris@16
|
113 operator()(const ChainedPtr& x)const
|
Chris@16
|
114 {
|
Chris@16
|
115 return operator()(*x);
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@16
|
118 Type operator()(Value x)const
|
Chris@16
|
119 {
|
Chris@16
|
120 return PtrToFunction(x);
|
Chris@16
|
121 }
|
Chris@16
|
122
|
Chris@16
|
123 Type operator()(
|
Chris@16
|
124 const reference_wrapper<
|
Chris@16
|
125 typename remove_reference<Value>::type>& x)const
|
Chris@16
|
126 {
|
Chris@16
|
127 return operator()(x.get());
|
Chris@16
|
128 }
|
Chris@16
|
129 };
|
Chris@16
|
130
|
Chris@16
|
131 template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
Chris@16
|
132 struct non_ref_global_fun_base
|
Chris@16
|
133 {
|
Chris@16
|
134 typedef typename remove_reference<Type>::type result_type;
|
Chris@16
|
135
|
Chris@16
|
136 template<typename ChainedPtr>
|
Chris@16
|
137
|
Chris@16
|
138 #if !defined(BOOST_NO_SFINAE)
|
Chris@16
|
139 typename disable_if<
|
Chris@16
|
140 is_convertible<const ChainedPtr&,const Value&>,Type>::type
|
Chris@16
|
141 #else
|
Chris@16
|
142 Type
|
Chris@16
|
143 #endif
|
Chris@16
|
144
|
Chris@16
|
145 operator()(const ChainedPtr& x)const
|
Chris@16
|
146 {
|
Chris@16
|
147 return operator()(*x);
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 Type operator()(const Value& x)const
|
Chris@16
|
151 {
|
Chris@16
|
152 return PtrToFunction(x);
|
Chris@16
|
153 }
|
Chris@16
|
154
|
Chris@16
|
155 Type operator()(const reference_wrapper<const Value>& x)const
|
Chris@16
|
156 {
|
Chris@16
|
157 return operator()(x.get());
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160 Type operator()(
|
Chris@16
|
161 const reference_wrapper<
|
Chris@16
|
162 typename remove_const<Value>::type>& x,int=0)const
|
Chris@16
|
163 {
|
Chris@16
|
164 return operator()(x.get());
|
Chris@16
|
165 }
|
Chris@16
|
166 };
|
Chris@16
|
167
|
Chris@16
|
168 } /* namespace multi_index::detail */
|
Chris@16
|
169
|
Chris@16
|
170 template<class Value,typename Type,Type (*PtrToFunction)(Value)>
|
Chris@16
|
171 struct global_fun:
|
Chris@16
|
172 mpl::if_c<
|
Chris@16
|
173 is_reference<Value>::value,
|
Chris@16
|
174 typename mpl::if_c<
|
Chris@16
|
175 is_const<typename remove_reference<Value>::type>::value,
|
Chris@16
|
176 detail::const_ref_global_fun_base<Value,Type,PtrToFunction>,
|
Chris@16
|
177 detail::non_const_ref_global_fun_base<Value,Type,PtrToFunction>
|
Chris@16
|
178 >::type,
|
Chris@16
|
179 detail::non_ref_global_fun_base<Value,Type,PtrToFunction>
|
Chris@16
|
180 >::type
|
Chris@16
|
181 {
|
Chris@16
|
182 };
|
Chris@16
|
183
|
Chris@16
|
184 } /* namespace multi_index */
|
Chris@16
|
185
|
Chris@16
|
186 } /* namespace boost */
|
Chris@16
|
187
|
Chris@16
|
188 #endif
|