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_MEM_FUN_HPP
|
williamr@2
|
10 |
#define BOOST_MULTI_INDEX_MEM_FUN_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/mpl/if.hpp>
|
williamr@2
|
18 |
#include <boost/type_traits/remove_reference.hpp>
|
williamr@2
|
19 |
#include <boost/utility/enable_if.hpp>
|
williamr@2
|
20 |
|
williamr@2
|
21 |
#if !defined(BOOST_NO_SFINAE)
|
williamr@2
|
22 |
#include <boost/type_traits/is_convertible.hpp>
|
williamr@2
|
23 |
#endif
|
williamr@2
|
24 |
|
williamr@2
|
25 |
namespace boost{
|
williamr@2
|
26 |
|
williamr@2
|
27 |
template<class T> class reference_wrapper; /* fwd decl. */
|
williamr@2
|
28 |
|
williamr@2
|
29 |
namespace multi_index{
|
williamr@2
|
30 |
|
williamr@2
|
31 |
/* mem_fun implements a read-only key extractor based on a given non-const
|
williamr@2
|
32 |
* member function of a class.
|
williamr@2
|
33 |
* const_mem_fun does the same for const member functions.
|
williamr@2
|
34 |
* Additionally, mem_fun and const_mem_fun are overloaded to support
|
williamr@2
|
35 |
* referece_wrappers of T and "chained pointers" to T's. By chained pointer
|
williamr@2
|
36 |
* to T we mean a type P such that, given a p of Type P
|
williamr@2
|
37 |
* *...n...*x is convertible to T&, for some n>=1.
|
williamr@2
|
38 |
* Examples of chained pointers are raw and smart pointers, iterators and
|
williamr@2
|
39 |
* arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
|
williamr@2
|
40 |
*/
|
williamr@2
|
41 |
|
williamr@2
|
42 |
/* NB. Some overloads of operator() have an extra dummy parameter int=0.
|
williamr@2
|
43 |
* This disambiguator serves several purposes:
|
williamr@2
|
44 |
* - Without it, MSVC++ 6.0 incorrectly regards some overloads as
|
williamr@2
|
45 |
* specializations of a previous member function template.
|
williamr@2
|
46 |
* - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
|
williamr@2
|
47 |
* as if they have the same signature.
|
williamr@2
|
48 |
* - If remove_const is broken due to lack of PTS, int=0 avoids the
|
williamr@2
|
49 |
* declaration of memfuns with identical signature.
|
williamr@2
|
50 |
*/
|
williamr@2
|
51 |
|
williamr@2
|
52 |
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
|
williamr@2
|
53 |
struct const_mem_fun
|
williamr@2
|
54 |
{
|
williamr@2
|
55 |
typedef typename remove_reference<Type>::type result_type;
|
williamr@2
|
56 |
|
williamr@2
|
57 |
template<typename ChainedPtr>
|
williamr@2
|
58 |
|
williamr@2
|
59 |
#if !defined(BOOST_NO_SFINAE)
|
williamr@2
|
60 |
typename disable_if<
|
williamr@2
|
61 |
is_convertible<const ChainedPtr&,const Class&>,Type>::type
|
williamr@2
|
62 |
#else
|
williamr@2
|
63 |
Type
|
williamr@2
|
64 |
#endif
|
williamr@2
|
65 |
|
williamr@2
|
66 |
operator()(const ChainedPtr& x)const
|
williamr@2
|
67 |
{
|
williamr@2
|
68 |
return operator()(*x);
|
williamr@2
|
69 |
}
|
williamr@2
|
70 |
|
williamr@2
|
71 |
Type operator()(const Class& x)const
|
williamr@2
|
72 |
{
|
williamr@2
|
73 |
return (x.*PtrToMemberFunction)();
|
williamr@2
|
74 |
}
|
williamr@2
|
75 |
|
williamr@2
|
76 |
Type operator()(const reference_wrapper<const Class>& x)const
|
williamr@2
|
77 |
{
|
williamr@2
|
78 |
return operator()(x.get());
|
williamr@2
|
79 |
}
|
williamr@2
|
80 |
|
williamr@2
|
81 |
Type operator()(const reference_wrapper<Class>& x,int=0)const
|
williamr@2
|
82 |
{
|
williamr@2
|
83 |
return operator()(x.get());
|
williamr@2
|
84 |
}
|
williamr@2
|
85 |
};
|
williamr@2
|
86 |
|
williamr@2
|
87 |
template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()>
|
williamr@2
|
88 |
struct mem_fun
|
williamr@2
|
89 |
{
|
williamr@2
|
90 |
typedef typename remove_reference<Type>::type result_type;
|
williamr@2
|
91 |
|
williamr@2
|
92 |
template<typename ChainedPtr>
|
williamr@2
|
93 |
|
williamr@2
|
94 |
#if !defined(BOOST_NO_SFINAE)
|
williamr@2
|
95 |
typename disable_if<
|
williamr@2
|
96 |
is_convertible<ChainedPtr&,Class&>,Type>::type
|
williamr@2
|
97 |
#else
|
williamr@2
|
98 |
Type
|
williamr@2
|
99 |
#endif
|
williamr@2
|
100 |
|
williamr@2
|
101 |
operator()(const ChainedPtr& x)const
|
williamr@2
|
102 |
{
|
williamr@2
|
103 |
return operator()(*x);
|
williamr@2
|
104 |
}
|
williamr@2
|
105 |
|
williamr@2
|
106 |
Type operator()(Class& x)const
|
williamr@2
|
107 |
{
|
williamr@2
|
108 |
return (x.*PtrToMemberFunction)();
|
williamr@2
|
109 |
}
|
williamr@2
|
110 |
|
williamr@2
|
111 |
Type operator()(const reference_wrapper<Class>& x)const
|
williamr@2
|
112 |
{
|
williamr@2
|
113 |
return operator()(x.get());
|
williamr@2
|
114 |
}
|
williamr@2
|
115 |
};
|
williamr@2
|
116 |
|
williamr@2
|
117 |
/* MSVC++ 6.0 has problems with const member functions as non-type template
|
williamr@2
|
118 |
* parameters, somehow it takes them as non-const. mem_fun_explicit workarounds
|
williamr@2
|
119 |
* this defficiency by accepting an extra type parameter that specifies the
|
williamr@2
|
120 |
* signature of he member function. The workaround was found at:
|
williamr@2
|
121 |
* Daniel, C.:"Re: weird typedef problem in VC",
|
williamr@2
|
122 |
* news:microsoft.public.vc.language, 21st nov 2002,
|
williamr@2
|
123 |
* http://groups.google.com/groups?
|
williamr@2
|
124 |
* hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05
|
williamr@2
|
125 |
*/
|
williamr@2
|
126 |
|
williamr@2
|
127 |
template<
|
williamr@2
|
128 |
class Class,typename Type,
|
williamr@2
|
129 |
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction>
|
williamr@2
|
130 |
struct const_mem_fun_explicit
|
williamr@2
|
131 |
{
|
williamr@2
|
132 |
typedef typename remove_reference<Type>::type result_type;
|
williamr@2
|
133 |
|
williamr@2
|
134 |
template<typename ChainedPtr>
|
williamr@2
|
135 |
|
williamr@2
|
136 |
#if !defined(BOOST_NO_SFINAE)
|
williamr@2
|
137 |
typename disable_if<
|
williamr@2
|
138 |
is_convertible<const ChainedPtr&,const Class&>,Type>::type
|
williamr@2
|
139 |
#else
|
williamr@2
|
140 |
Type
|
williamr@2
|
141 |
#endif
|
williamr@2
|
142 |
|
williamr@2
|
143 |
operator()(const ChainedPtr& x)const
|
williamr@2
|
144 |
{
|
williamr@2
|
145 |
return operator()(*x);
|
williamr@2
|
146 |
}
|
williamr@2
|
147 |
|
williamr@2
|
148 |
Type operator()(const Class& x)const
|
williamr@2
|
149 |
{
|
williamr@2
|
150 |
return (x.*PtrToMemberFunction)();
|
williamr@2
|
151 |
}
|
williamr@2
|
152 |
|
williamr@2
|
153 |
Type operator()(const reference_wrapper<const Class>& x)const
|
williamr@2
|
154 |
{
|
williamr@2
|
155 |
return operator()(x.get());
|
williamr@2
|
156 |
}
|
williamr@2
|
157 |
|
williamr@2
|
158 |
Type operator()(const reference_wrapper<Class>& x,int=0)const
|
williamr@2
|
159 |
{
|
williamr@2
|
160 |
return operator()(x.get());
|
williamr@2
|
161 |
}
|
williamr@2
|
162 |
};
|
williamr@2
|
163 |
|
williamr@2
|
164 |
template<
|
williamr@2
|
165 |
class Class,typename Type,
|
williamr@2
|
166 |
typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction>
|
williamr@2
|
167 |
struct mem_fun_explicit
|
williamr@2
|
168 |
{
|
williamr@2
|
169 |
typedef typename remove_reference<Type>::type result_type;
|
williamr@2
|
170 |
|
williamr@2
|
171 |
template<typename ChainedPtr>
|
williamr@2
|
172 |
|
williamr@2
|
173 |
#if !defined(BOOST_NO_SFINAE)
|
williamr@2
|
174 |
typename disable_if<
|
williamr@2
|
175 |
is_convertible<ChainedPtr&,Class&>,Type>::type
|
williamr@2
|
176 |
#else
|
williamr@2
|
177 |
Type
|
williamr@2
|
178 |
#endif
|
williamr@2
|
179 |
|
williamr@2
|
180 |
operator()(const ChainedPtr& x)const
|
williamr@2
|
181 |
{
|
williamr@2
|
182 |
return operator()(*x);
|
williamr@2
|
183 |
}
|
williamr@2
|
184 |
|
williamr@2
|
185 |
Type operator()(Class& x)const
|
williamr@2
|
186 |
{
|
williamr@2
|
187 |
return (x.*PtrToMemberFunction)();
|
williamr@2
|
188 |
}
|
williamr@2
|
189 |
|
williamr@2
|
190 |
Type operator()(const reference_wrapper<Class>& x)const
|
williamr@2
|
191 |
{
|
williamr@2
|
192 |
return operator()(x.get());
|
williamr@2
|
193 |
}
|
williamr@2
|
194 |
};
|
williamr@2
|
195 |
|
williamr@2
|
196 |
/* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN resolve to
|
williamr@2
|
197 |
* mem_fun_explicit for MSVC++ 6.0 and to [const_]mem_fun otherwise.
|
williamr@2
|
198 |
*/
|
williamr@2
|
199 |
|
williamr@2
|
200 |
#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300)
|
williamr@2
|
201 |
|
williamr@2
|
202 |
#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \
|
williamr@2
|
203 |
::boost::multi_index::const_mem_fun_explicit<\
|
williamr@2
|
204 |
Class,Type,Type (Class::*)()const,&Class::MemberFunName >
|
williamr@2
|
205 |
#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \
|
williamr@2
|
206 |
::boost::multi_index::mem_fun_explicit<\
|
williamr@2
|
207 |
Class,Type,Type (Class::*)(),&Class::MemberFunName >
|
williamr@2
|
208 |
|
williamr@2
|
209 |
#else
|
williamr@2
|
210 |
|
williamr@2
|
211 |
#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \
|
williamr@2
|
212 |
::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName >
|
williamr@2
|
213 |
#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \
|
williamr@2
|
214 |
::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName >
|
williamr@2
|
215 |
|
williamr@2
|
216 |
#endif
|
williamr@2
|
217 |
|
williamr@2
|
218 |
} /* namespace multi_index */
|
williamr@2
|
219 |
|
williamr@2
|
220 |
} /* namespace boost */
|
williamr@2
|
221 |
|
williamr@2
|
222 |
#endif
|