Line data Source code
1 : #ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED
2 : #define BOOST_BIND_MEM_FN_HPP_INCLUDED
3 :
4 : // MS compatible compilers support #pragma once
5 :
6 : #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 : # pragma once
8 : #endif
9 :
10 : //
11 : // mem_fn.hpp - a generalization of std::mem_fun[_ref]
12 : //
13 : // Copyright 2001-2005, 2024 Peter Dimov
14 : // Copyright 2001 David Abrahams
15 : //
16 : // Distributed under the Boost Software License, Version 1.0. (See
17 : // accompanying file LICENSE_1_0.txt or copy at
18 : // http://www.boost.org/LICENSE_1_0.txt)
19 : //
20 : // See http://www.boost.org/libs/bind/mem_fn.html for documentation.
21 : //
22 :
23 : #include <boost/get_pointer.hpp>
24 : #include <boost/config.hpp>
25 : #include <boost/config/workaround.hpp>
26 : #include <type_traits>
27 :
28 : namespace boost
29 : {
30 :
31 : namespace _mfi
32 : {
33 :
34 : template<class T> struct remove_cvref: std::remove_cv< typename std::remove_reference<T>::type >
35 : {
36 : };
37 :
38 : template<class Pm, class R, class T, class... A> class mf
39 : {
40 : public:
41 :
42 : typedef R result_type;
43 :
44 : private:
45 :
46 : Pm pm_;
47 :
48 : public:
49 :
50 43216 : mf( Pm pm ): pm_( pm ) {}
51 :
52 : template<class U,
53 : class Ud = typename _mfi::remove_cvref<U>::type,
54 : class En = typename std::enable_if<
55 : std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value
56 : >::type
57 : >
58 :
59 21170 : R operator()( U&& u, A... a ) const
60 : {
61 21170 : return (std::forward<U>( u ).*pm_)( std::forward<A>( a )... );
62 : }
63 :
64 : template<class U,
65 : class Ud = typename _mfi::remove_cvref<U>::type,
66 : class E1 = void,
67 : class En = typename std::enable_if<
68 : !(std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value)
69 : >::type
70 : >
71 :
72 438 : R operator()( U&& u, A... a ) const
73 : {
74 438 : return (get_pointer( std::forward<U>( u ) )->*pm_)( std::forward<A>( a )... );
75 : }
76 :
77 : bool operator==( mf const & rhs ) const
78 : {
79 : return pm_ == rhs.pm_;
80 : }
81 :
82 : bool operator!=( mf const & rhs ) const
83 : {
84 : return pm_ != rhs.pm_;
85 : }
86 : };
87 :
88 : } // namespace _mfi
89 :
90 : //
91 :
92 : template<class R, class T, class... A>
93 438 : auto mem_fn( R (T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
94 : {
95 438 : return pmf;
96 : }
97 :
98 : template<class R, class T, class... A>
99 21170 : auto mem_fn( R (T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
100 : {
101 21170 : return pmf;
102 : }
103 :
104 : #if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
105 :
106 : template<class R, class T, class... A>
107 : auto mem_fn( R (T::*pmf) (A...) noexcept ) -> _mfi::mf<decltype(pmf), R, T, A...>
108 : {
109 : return pmf;
110 : }
111 :
112 : template<class R, class T, class... A>
113 : auto mem_fn( R (T::*pmf) (A...) const noexcept ) -> _mfi::mf<decltype(pmf), R, T, A...>
114 : {
115 : return pmf;
116 : }
117 :
118 : #endif // #if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
119 :
120 : #if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64)
121 :
122 : template<class R, class T, class... A>
123 : auto mem_fn( R (__cdecl T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
124 : {
125 : return pmf;
126 : }
127 :
128 : template<class R, class T, class... A>
129 : auto mem_fn( R (__cdecl T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
130 : {
131 : return pmf;
132 : }
133 :
134 : #endif // #if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64)
135 :
136 : #if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64)
137 :
138 : template<class R, class T, class... A>
139 : auto mem_fn( R (__stdcall T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
140 : {
141 : return pmf;
142 : }
143 :
144 : template<class R, class T, class... A>
145 : auto mem_fn( R (__stdcall T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
146 : {
147 : return pmf;
148 : }
149 :
150 : #endif // #if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64)
151 :
152 : #if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64)
153 :
154 : template<class R, class T, class... A>
155 : auto mem_fn( R (__fastcall T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
156 : {
157 : return pmf;
158 : }
159 :
160 : template<class R, class T, class... A>
161 : auto mem_fn( R (__fastcall T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
162 : {
163 : return pmf;
164 : }
165 :
166 : #endif // #if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64)
167 :
168 : // data member support
169 :
170 : namespace _mfi
171 : {
172 :
173 : template<class R, class T> class dm
174 : {
175 : public:
176 :
177 : typedef R const & result_type;
178 : typedef T const * argument_type;
179 :
180 : private:
181 :
182 : typedef R (T::*Pm);
183 : Pm pm_;
184 :
185 : public:
186 :
187 : dm( Pm pm ): pm_( pm ) {}
188 :
189 : template<class U,
190 : class Ud = typename _mfi::remove_cvref<U>::type,
191 : class En = typename std::enable_if<
192 : std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value
193 : >::type
194 : >
195 :
196 : auto operator()( U&& u ) const -> decltype( std::forward<U>( u ).*pm_ )
197 : {
198 : return std::forward<U>( u ).*pm_;
199 : }
200 :
201 : template<class U,
202 : class Ud = typename _mfi::remove_cvref<U>::type,
203 : class E1 = void,
204 : class En = typename std::enable_if<
205 : !(std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value)
206 : >::type
207 : >
208 :
209 : auto operator()( U&& u ) const -> decltype( get_pointer( std::forward<U>( u ) )->*pm_ )
210 : {
211 : return get_pointer( std::forward<U>( u ) )->*pm_;
212 : }
213 :
214 : #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
215 :
216 : template<class U>
217 : R& operator()( U* u ) const
218 : {
219 : return u->*pm_;
220 : }
221 :
222 : template<class U>
223 : R const& operator()( U const* u ) const
224 : {
225 : return u->*pm_;
226 : }
227 :
228 : #endif
229 :
230 : bool operator==( dm const & rhs ) const
231 : {
232 : return pm_ == rhs.pm_;
233 : }
234 :
235 : bool operator!=( dm const & rhs ) const
236 : {
237 : return pm_ != rhs.pm_;
238 : }
239 : };
240 :
241 : } // namespace _mfi
242 :
243 : template<class R, class T,
244 : class E = typename std::enable_if< !std::is_function<R>::value >::type
245 : >
246 : _mfi::dm<R, T> mem_fn( R T::*pm )
247 : {
248 : return pm;
249 : }
250 :
251 : } // namespace boost
252 :
253 : #endif // #ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED
|