]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* Copyright 2003-2015 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 | * const_mem_fun does the same for const member functions. | |
34 | * Additionally, mem_fun and const_mem_fun are overloaded to support | |
35 | * referece_wrappers of T and "chained pointers" to T's. By chained pointer | |
36 | * to T we mean a type P such that, given a p of Type P | |
37 | * *...n...*x is convertible to T&, for some n>=1. | |
38 | * Examples of chained pointers are raw and smart pointers, iterators and | |
39 | * arbitrary combinations of these (vg. T** or unique_ptr<T*>.) | |
40 | */ | |
41 | ||
42 | template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const> | |
43 | struct const_mem_fun | |
44 | { | |
45 | typedef typename remove_reference<Type>::type result_type; | |
46 | ||
47 | template<typename ChainedPtr> | |
48 | ||
49 | #if !defined(BOOST_NO_SFINAE) | |
50 | typename disable_if< | |
51 | is_convertible<const ChainedPtr&,const Class&>,Type>::type | |
52 | #else | |
53 | Type | |
54 | #endif | |
55 | ||
56 | operator()(const ChainedPtr& x)const | |
57 | { | |
58 | return operator()(*x); | |
59 | } | |
60 | ||
61 | Type operator()(const Class& x)const | |
62 | { | |
63 | return (x.*PtrToMemberFunction)(); | |
64 | } | |
65 | ||
66 | Type operator()(const reference_wrapper<const Class>& x)const | |
67 | { | |
68 | return operator()(x.get()); | |
69 | } | |
70 | ||
71 | Type operator()(const reference_wrapper<Class>& x)const | |
72 | { | |
73 | return operator()(x.get()); | |
74 | } | |
75 | }; | |
76 | ||
77 | template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()> | |
78 | struct mem_fun | |
79 | { | |
80 | typedef typename remove_reference<Type>::type result_type; | |
81 | ||
82 | template<typename ChainedPtr> | |
83 | ||
84 | #if !defined(BOOST_NO_SFINAE) | |
85 | typename disable_if< | |
86 | is_convertible<ChainedPtr&,Class&>,Type>::type | |
87 | #else | |
88 | Type | |
89 | #endif | |
90 | ||
91 | operator()(const ChainedPtr& x)const | |
92 | { | |
93 | return operator()(*x); | |
94 | } | |
95 | ||
96 | Type operator()(Class& x)const | |
97 | { | |
98 | return (x.*PtrToMemberFunction)(); | |
99 | } | |
100 | ||
101 | Type operator()(const reference_wrapper<Class>& x)const | |
102 | { | |
103 | return operator()(x.get()); | |
104 | } | |
105 | }; | |
106 | ||
107 | /* MSVC++ 6.0 has problems with const member functions as non-type template | |
108 | * parameters, somehow it takes them as non-const. const_mem_fun_explicit | |
109 | * workarounds this deficiency by accepting an extra type parameter that | |
110 | * specifies the signature of the member function. The workaround was found at: | |
111 | * Daniel, C.:"Re: weird typedef problem in VC", | |
112 | * news:microsoft.public.vc.language, 21st nov 2002, | |
113 | * http://groups.google.com/groups? | |
114 | * hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05 | |
115 | * | |
116 | * MSVC++ 6.0 support has been dropped and [const_]mem_fun_explicit is | |
117 | * deprecated. | |
118 | */ | |
119 | ||
120 | template< | |
121 | class Class,typename Type, | |
122 | typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> | |
123 | struct const_mem_fun_explicit | |
124 | { | |
125 | typedef typename remove_reference<Type>::type result_type; | |
126 | ||
127 | template<typename ChainedPtr> | |
128 | ||
129 | #if !defined(BOOST_NO_SFINAE) | |
130 | typename disable_if< | |
131 | is_convertible<const ChainedPtr&,const Class&>,Type>::type | |
132 | #else | |
133 | Type | |
134 | #endif | |
135 | ||
136 | operator()(const ChainedPtr& x)const | |
137 | { | |
138 | return operator()(*x); | |
139 | } | |
140 | ||
141 | Type operator()(const Class& x)const | |
142 | { | |
143 | return (x.*PtrToMemberFunction)(); | |
144 | } | |
145 | ||
146 | Type operator()(const reference_wrapper<const Class>& x)const | |
147 | { | |
148 | return operator()(x.get()); | |
149 | } | |
150 | ||
151 | Type operator()(const reference_wrapper<Class>& x)const | |
152 | { | |
153 | return operator()(x.get()); | |
154 | } | |
155 | }; | |
156 | ||
157 | template< | |
158 | class Class,typename Type, | |
159 | typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> | |
160 | struct mem_fun_explicit | |
161 | { | |
162 | typedef typename remove_reference<Type>::type result_type; | |
163 | ||
164 | template<typename ChainedPtr> | |
165 | ||
166 | #if !defined(BOOST_NO_SFINAE) | |
167 | typename disable_if< | |
168 | is_convertible<ChainedPtr&,Class&>,Type>::type | |
169 | #else | |
170 | Type | |
171 | #endif | |
172 | ||
173 | operator()(const ChainedPtr& x)const | |
174 | { | |
175 | return operator()(*x); | |
176 | } | |
177 | ||
178 | Type operator()(Class& x)const | |
179 | { | |
180 | return (x.*PtrToMemberFunction)(); | |
181 | } | |
182 | ||
183 | Type operator()(const reference_wrapper<Class>& x)const | |
184 | { | |
185 | return operator()(x.get()); | |
186 | } | |
187 | }; | |
188 | ||
189 | /* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN used to | |
190 | * resolve to [const_]mem_fun_explicit for MSVC++ 6.0 and to | |
191 | * [const_]mem_fun otherwise. Support for this compiler having been dropped, | |
192 | * they are now just wrappers over [const_]mem_fun kept for backwards- | |
193 | * compatibility reasons. | |
194 | */ | |
195 | ||
196 | #define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \ | |
197 | ::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName > | |
198 | #define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \ | |
199 | ::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName > | |
200 | ||
201 | } /* namespace multi_index */ | |
202 | ||
203 | } /* namespace boost */ | |
204 | ||
205 | #endif |