• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2003-2019 Joaquin M Lopez Munoz.
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_MEM_FUN_HPP
10 #define BOOST_MULTI_INDEX_MEM_FUN_HPP
11 
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15 
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <boost/mpl/if.hpp>
18 #include <boost/type_traits/remove_reference.hpp>
19 #include <boost/utility/enable_if.hpp>
20 
21 #if !defined(BOOST_NO_SFINAE)
22 #include <boost/type_traits/is_convertible.hpp>
23 #endif
24 
25 namespace boost{
26 
27 template<class T> class reference_wrapper; /* fwd decl. */
28 
29 namespace multi_index{
30 
31 /* mem_fun implements a read-only key extractor based on a given non-const
32  * member function of a class.
33  * Also, the following variations are provided:
34  *   const_mem_fun:    const member functions
35  *   volatile_mem_fun: volatile member functions
36  *   cv_mem_fun:       const volatile member functions
37  *   ref_mem_fun:      ref-qualifed member functions (C++11)
38  *   cref_mem_fun:     const ref-qualifed member functions (C++11)
39  *   vref_mem_fun:     volatile ref-qualifed member functions (C++11)
40  *   cvref_mem_fun:    const volatile ref-qualifed member functions (C++11)
41  *
42  * All of these classes are overloaded to support boost::referece_wrappers
43  * of T and "chained pointers" to T's. By chained pointer to T we mean a type
44  * P such that, given a p of Type P
45  *   *...n...*x is convertible to T&, for some n>=1.
46  * Examples of chained pointers are raw and smart pointers, iterators and
47  * arbitrary combinations of these (vg. T** or unique_ptr<T*>.)
48  */
49 
50 namespace detail{
51 
52 template<
53   class Class,typename Type,
54   typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
55 >
56 struct const_mem_fun_impl
57 {
58   typedef typename remove_reference<Type>::type result_type;
59 
60   template<typename ChainedPtr>
61 
62 #if !defined(BOOST_NO_SFINAE)
63   typename disable_if<
64     is_convertible<const ChainedPtr&,const Class&>,Type>::type
65 #else
66   Type
67 #endif
68 
operator ()boost::multi_index::detail::const_mem_fun_impl69   operator()(const ChainedPtr& x)const
70   {
71     return operator()(*x);
72   }
73 
operator ()boost::multi_index::detail::const_mem_fun_impl74   Type operator()(const Class& x)const
75   {
76     return (x.*PtrToMemberFunction)();
77   }
78 
operator ()boost::multi_index::detail::const_mem_fun_impl79   Type operator()(const reference_wrapper<const Class>& x)const
80   {
81     return operator()(x.get());
82   }
83 
operator ()boost::multi_index::detail::const_mem_fun_impl84   Type operator()(const reference_wrapper<Class>& x)const
85   {
86     return operator()(x.get());
87   }
88 };
89 
90 template<
91   class Class,typename Type,
92   typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
93 >
94 struct mem_fun_impl
95 {
96   typedef typename remove_reference<Type>::type result_type;
97 
98   template<typename ChainedPtr>
99 
100 #if !defined(BOOST_NO_SFINAE)
101   typename disable_if<
102     is_convertible<ChainedPtr&,Class&>,Type>::type
103 #else
104   Type
105 #endif
106 
operator ()boost::multi_index::detail::mem_fun_impl107   operator()(const ChainedPtr& x)const
108   {
109     return operator()(*x);
110   }
111 
operator ()boost::multi_index::detail::mem_fun_impl112   Type operator()(Class& x)const
113   {
114     return (x.*PtrToMemberFunction)();
115   }
116 
operator ()boost::multi_index::detail::mem_fun_impl117   Type operator()(const reference_wrapper<Class>& x)const
118   {
119     return operator()(x.get());
120   }
121 };
122 
123 } /* namespace multi_index::detail */
124 
125 template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
126 struct const_mem_fun:detail::const_mem_fun_impl<
127   Class,Type,Type (Class::*)()const,PtrToMemberFunction
128 >{};
129 
130 template<
131   class Class,typename Type,
132   Type (Class::*PtrToMemberFunction)()const volatile
133 >
134 struct cv_mem_fun:detail::const_mem_fun_impl<
135   Class,Type,Type (Class::*)()const volatile,PtrToMemberFunction
136 >{};
137 
138 template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()>
139 struct mem_fun:
140   detail::mem_fun_impl<Class,Type,Type (Class::*)(),PtrToMemberFunction>{};
141 
142 template<
143   class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile
144 >
145 struct volatile_mem_fun:detail::mem_fun_impl<
146   Class,Type,Type (Class::*)()volatile,PtrToMemberFunction
147 >{};
148 
149 #if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
150 
151 template<
152   class Class,typename Type,Type (Class::*PtrToMemberFunction)()const&
153 >
154 struct cref_mem_fun:detail::const_mem_fun_impl<
155   Class,Type,Type (Class::*)()const&,PtrToMemberFunction
156 >{};
157 
158 template<
159   class Class,typename Type,
160   Type (Class::*PtrToMemberFunction)()const volatile&
161 >
162 struct cvref_mem_fun:detail::const_mem_fun_impl<
163   Class,Type,Type (Class::*)()const volatile&,PtrToMemberFunction
164 >{};
165 
166 template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()&>
167 struct ref_mem_fun:
168   detail::mem_fun_impl<Class,Type,Type (Class::*)()&,PtrToMemberFunction>{};
169 
170 template<
171   class Class,typename Type,Type (Class::*PtrToMemberFunction)()volatile&
172 >
173 struct vref_mem_fun:detail::mem_fun_impl<
174   Class,Type,Type (Class::*)()volatile&,PtrToMemberFunction
175 >{};
176 
177 #endif
178 
179 /* MSVC++ 6.0 has problems with const member functions as non-type template
180  * parameters, somehow it takes them as non-const. const_mem_fun_explicit
181  * workarounds this deficiency by accepting an extra type parameter that
182  * specifies the signature of the member function. The workaround was found at:
183  *   Daniel, C.:"Re: weird typedef problem in VC",
184  *   news:microsoft.public.vc.language, 21st nov 2002,
185  *   http://groups.google.com/groups?
186  *     hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05
187  *
188  * MSVC++ 6.0 support has been dropped and [const_]mem_fun_explicit is
189  * deprecated.
190  */
191 
192 template<
193   class Class,typename Type,
194   typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
195 >
196 struct const_mem_fun_explicit
197 {
198   typedef typename remove_reference<Type>::type result_type;
199 
200   template<typename ChainedPtr>
201 
202 #if !defined(BOOST_NO_SFINAE)
203   typename disable_if<
204     is_convertible<const ChainedPtr&,const Class&>,Type>::type
205 #else
206   Type
207 #endif
208 
operator ()boost::multi_index::const_mem_fun_explicit209   operator()(const ChainedPtr& x)const
210   {
211     return operator()(*x);
212   }
213 
operator ()boost::multi_index::const_mem_fun_explicit214   Type operator()(const Class& x)const
215   {
216     return (x.*PtrToMemberFunction)();
217   }
218 
operator ()boost::multi_index::const_mem_fun_explicit219   Type operator()(const reference_wrapper<const Class>& x)const
220   {
221     return operator()(x.get());
222   }
223 
operator ()boost::multi_index::const_mem_fun_explicit224   Type operator()(const reference_wrapper<Class>& x)const
225   {
226     return operator()(x.get());
227   }
228 };
229 
230 template<
231   class Class,typename Type,
232   typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction
233 >
234 struct mem_fun_explicit
235 {
236   typedef typename remove_reference<Type>::type result_type;
237 
238   template<typename ChainedPtr>
239 
240 #if !defined(BOOST_NO_SFINAE)
241   typename disable_if<
242     is_convertible<ChainedPtr&,Class&>,Type>::type
243 #else
244   Type
245 #endif
246 
operator ()boost::multi_index::mem_fun_explicit247   operator()(const ChainedPtr& x)const
248   {
249     return operator()(*x);
250   }
251 
operator ()boost::multi_index::mem_fun_explicit252   Type operator()(Class& x)const
253   {
254     return (x.*PtrToMemberFunction)();
255   }
256 
operator ()boost::multi_index::mem_fun_explicit257   Type operator()(const reference_wrapper<Class>& x)const
258   {
259     return operator()(x.get());
260   }
261 };
262 
263 /* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN used to
264  * resolve to [const_]mem_fun_explicit for MSVC++ 6.0 and to
265  * [const_]mem_fun otherwise. Support for this compiler having been dropped,
266  * they are now just wrappers over [const_]mem_fun kept for backwards-
267  * compatibility reasons.
268  */
269 
270 #define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \
271 ::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName >
272 #define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \
273 ::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName >
274 
275 } /* namespace multi_index */
276 
277 } /* namespace boost */
278 
279 #endif
280