1 | #ifndef BOOST_BIND_BIND_HPP_INCLUDED |
2 | #define BOOST_BIND_BIND_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 | // bind.hpp - binds function objects to arguments |
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 for documentation. |
21 | // |
22 | |
23 | #include <boost/bind/mem_fn.hpp> |
24 | #include <boost/bind/arg.hpp> |
25 | #include <boost/bind/std_placeholders.hpp> |
26 | #include <boost/bind/detail/result_traits.hpp> |
27 | #include <boost/bind/detail/tuple_for_each.hpp> |
28 | #include <boost/bind/detail/integer_sequence.hpp> |
29 | #include <boost/visit_each.hpp> |
30 | #include <boost/is_placeholder.hpp> |
31 | #include <boost/type.hpp> |
32 | #include <boost/core/ref.hpp> |
33 | #include <boost/config.hpp> |
34 | #include <boost/config/workaround.hpp> |
35 | #include <utility> |
36 | #include <type_traits> |
37 | #include <tuple> |
38 | |
39 | #ifdef BOOST_MSVC |
40 | # pragma warning(push) |
41 | # pragma warning(disable: 4512) // assignment operator could not be generated |
42 | #endif |
43 | |
44 | namespace boost |
45 | { |
46 | |
47 | template<class T> class weak_ptr; |
48 | |
49 | namespace _bi // implementation details |
50 | { |
51 | |
52 | // ref_compare |
53 | |
54 | template<class T> bool ref_compare( T const & a, T const & b ) |
55 | { |
56 | return a == b; |
57 | } |
58 | |
59 | template<int I> bool ref_compare( arg<I> const &, arg<I> const & ) |
60 | { |
61 | return true; |
62 | } |
63 | |
64 | template<int I> bool ref_compare( arg<I> (*) (), arg<I> (*) () ) |
65 | { |
66 | return true; |
67 | } |
68 | |
69 | template<class T> bool ref_compare( reference_wrapper<T> const & a, reference_wrapper<T> const & b ) |
70 | { |
71 | return a.get_pointer() == b.get_pointer(); |
72 | } |
73 | |
74 | // bind_t forward declaration for listN |
75 | |
76 | template<class R, class F, class L> class bind_t; |
77 | |
78 | template<class R, class F, class L> bool ref_compare( bind_t<R, F, L> const & a, bind_t<R, F, L> const & b ) |
79 | { |
80 | return a.compare( b ); |
81 | } |
82 | |
83 | // value |
84 | |
85 | template<class T> class value |
86 | { |
87 | public: |
88 | |
89 | value(T const & t): t_(t) {} |
90 | |
91 | T & get() { return t_; } |
92 | T const & get() const { return t_; } |
93 | |
94 | bool operator==(value const & rhs) const |
95 | { |
96 | return t_ == rhs.t_; |
97 | } |
98 | |
99 | private: |
100 | |
101 | T t_; |
102 | }; |
103 | |
104 | // ref_compare for weak_ptr |
105 | |
106 | template<class T> bool ref_compare( value< weak_ptr<T> > const & a, value< weak_ptr<T> > const & b ) |
107 | { |
108 | return !(a.get() < b.get()) && !(b.get() < a.get()); |
109 | } |
110 | |
111 | // type |
112 | |
113 | template<class T> class type {}; |
114 | |
115 | // unwrap |
116 | |
117 | template<class F> struct unwrapper |
118 | { |
119 | static inline F & unwrap( F & f, long ) |
120 | { |
121 | return f; |
122 | } |
123 | |
124 | template<class F2> static inline F2 & unwrap( reference_wrapper<F2> rf, int ) |
125 | { |
126 | return rf.get(); |
127 | } |
128 | |
129 | template<class R, class T> static inline _mfi::dm<R, T> unwrap( R T::* pm, int ) |
130 | { |
131 | return _mfi::dm<R, T>( pm ); |
132 | } |
133 | }; |
134 | |
135 | // list |
136 | |
137 | template<class V> struct accept_lambda |
138 | { |
139 | V& v_; |
140 | |
141 | explicit accept_lambda( V& v ): v_( v ) {} |
142 | |
143 | template<class A> void operator()( A& a ) const |
144 | { |
145 | visit_each( v_, a, 0 ); |
146 | } |
147 | }; |
148 | |
149 | struct equal_lambda |
150 | { |
151 | bool result; |
152 | |
153 | equal_lambda(): result( true ) {} |
154 | |
155 | template<class A1, class A2> void operator()( A1& a1, A2& a2 ) |
156 | { |
157 | result = result && ref_compare( a1, a2 ); |
158 | } |
159 | }; |
160 | |
161 | struct logical_and; |
162 | struct logical_or; |
163 | |
164 | template<class... A> class list |
165 | { |
166 | private: |
167 | |
168 | typedef std::tuple<A...> data_type; |
169 | data_type data_; |
170 | |
171 | public: |
172 | |
173 | list( A... a ): data_( a... ) {} |
174 | |
175 | #if defined(BOOST_MSVC) |
176 | # pragma warning( push ) |
177 | # pragma warning( disable: 4100 ) // unreferenced formal parameter 'a2' |
178 | #endif |
179 | |
180 | template<class R, class F, class A2, std::size_t... I> R call_impl( type<R>, F & f, A2 & a2, _bi::index_sequence<I...> ) |
181 | { |
182 | return unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... ); |
183 | } |
184 | |
185 | template<class R, class F, class A2, std::size_t... I> R call_impl( type<R>, F & f, A2 & a2, _bi::index_sequence<I...> ) const |
186 | { |
187 | return unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... ); |
188 | } |
189 | |
190 | template<class F, class A2, std::size_t... I> void call_impl( type<void>, F & f, A2 & a2, _bi::index_sequence<I...> ) |
191 | { |
192 | unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... ); |
193 | } |
194 | |
195 | template<class F, class A2, std::size_t... I> void call_impl( type<void>, F & f, A2 & a2, _bi::index_sequence<I...> ) const |
196 | { |
197 | unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... ); |
198 | } |
199 | |
200 | #if defined(BOOST_MSVC) |
201 | # pragma warning( pop ) |
202 | #endif |
203 | |
204 | // |
205 | |
206 | template<class R, class F, class A2> R operator()( type<R>, F & f, A2 & a2 ) |
207 | { |
208 | return call_impl( type<R>(), f, a2, _bi::index_sequence_for<A...>() ); |
209 | } |
210 | |
211 | template<class R, class F, class A2> R operator()( type<R>, F & f, A2 & a2 ) const |
212 | { |
213 | return call_impl( type<R>(), f, a2, _bi::index_sequence_for<A...>() ); |
214 | } |
215 | |
216 | // |
217 | |
218 | template<class A2> bool operator()( type<bool>, logical_and & /*f*/, A2 & a2 ) |
219 | { |
220 | static_assert( sizeof...(A) == 2, "operator&& must have two arguments" ); |
221 | return a2[ std::get<0>( data_ ) ] && a2[ std::get<1>( data_ ) ]; |
222 | } |
223 | |
224 | template<class A2> bool operator()( type<bool>, logical_and const & /*f*/, A2 & a2 ) const |
225 | { |
226 | static_assert( sizeof...(A) == 2, "operator&& must have two arguments" ); |
227 | return a2[ std::get<0>( data_ ) ] && a2[ std::get<1>( data_ ) ]; |
228 | } |
229 | |
230 | template<class A2> bool operator()( type<bool>, logical_or & /*f*/, A2 & a2 ) |
231 | { |
232 | static_assert( sizeof...(A) == 2, "operator|| must have two arguments" ); |
233 | return a2[ std::get<0>( data_ ) ] || a2[ std::get<1>( data_ ) ]; |
234 | } |
235 | |
236 | template<class A2> bool operator()( type<bool>, logical_or const & /*f*/, A2 & a2 ) const |
237 | { |
238 | static_assert( sizeof...(A) == 2, "operator|| must have two arguments" ); |
239 | return a2[ std::get<0>( data_ ) ] || a2[ std::get<1>( data_ ) ]; |
240 | } |
241 | |
242 | // |
243 | |
244 | template<class V> void accept( V & v ) const |
245 | { |
246 | _bi::tuple_for_each( accept_lambda<V>( v ), data_ ); |
247 | } |
248 | |
249 | bool operator==( list const & rhs ) const |
250 | { |
251 | return _bi::tuple_for_each( equal_lambda(), data_, rhs.data_ ).result; |
252 | } |
253 | }; |
254 | |
255 | // bind_t |
256 | |
257 | template<class... A> class rrlist |
258 | { |
259 | private: |
260 | |
261 | using args_type = std::tuple<A...>; |
262 | |
263 | using data_type = std::tuple<A&...>; |
264 | data_type data_; |
265 | |
266 | template<class...> friend class rrlist; |
267 | |
268 | public: |
269 | |
270 | explicit rrlist( A&... a ): data_( a... ) {} |
271 | template<class... B> explicit rrlist( rrlist<B...> const& r ): data_( r.data_ ) {} |
272 | |
273 | template<int I> typename std::tuple_element<I-1, args_type>::type&& operator[] ( boost::arg<I> ) const |
274 | { |
275 | return std::forward<typename std::tuple_element<I-1, args_type>::type>( std::get<I-1>( data_ ) ); |
276 | } |
277 | |
278 | template<int I> typename std::tuple_element<I-1, args_type>::type&& operator[] ( boost::arg<I>(*)() ) const |
279 | { |
280 | return std::forward<typename std::tuple_element<I-1, args_type>::type>( std::get<I-1>( data_ ) ); |
281 | } |
282 | |
283 | template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); } |
284 | |
285 | template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); } |
286 | |
287 | template<class T> T & operator[] ( reference_wrapper<T> const & v ) const { return v.get(); } |
288 | |
289 | template<class R, class F, class L> typename result_traits<R, F>::type operator[] ( bind_t<R, F, L> & b ) const |
290 | { |
291 | rrlist<A&...> a2( *this ); |
292 | return b.eval( a2 ); |
293 | } |
294 | |
295 | template<class R, class F, class L> typename result_traits<R, F>::type operator[] ( bind_t<R, F, L> const & b ) const |
296 | { |
297 | rrlist<A&...> a2( *this ); |
298 | return b.eval( a2 ); |
299 | } |
300 | }; |
301 | |
302 | template<class R, class F, class L> class bind_t |
303 | { |
304 | private: |
305 | |
306 | F f_; |
307 | L l_; |
308 | |
309 | public: |
310 | |
311 | typedef typename result_traits<R, F>::type result_type; |
312 | typedef bind_t this_type; |
313 | |
314 | bind_t( F f, L const & l ): f_( std::move(f) ), l_( l ) {} |
315 | |
316 | // |
317 | |
318 | template<class... A> result_type operator()( A&&... a ) |
319 | { |
320 | rrlist<A...> a2( a... ); |
321 | return l_( type<result_type>(), f_, a2 ); |
322 | } |
323 | |
324 | template<class... A> result_type operator()( A&&... a ) const |
325 | { |
326 | rrlist<A...> a2( a... ); |
327 | return l_( type<result_type>(), f_, a2 ); |
328 | } |
329 | |
330 | // |
331 | |
332 | template<class A> result_type eval( A & a ) |
333 | { |
334 | return l_( type<result_type>(), f_, a ); |
335 | } |
336 | |
337 | template<class A> result_type eval( A & a ) const |
338 | { |
339 | return l_( type<result_type>(), f_, a ); |
340 | } |
341 | |
342 | template<class V> void accept( V & v ) const |
343 | { |
344 | using boost::visit_each; |
345 | visit_each( v, f_, 0 ); |
346 | l_.accept( v ); |
347 | } |
348 | |
349 | bool compare( this_type const & rhs ) const |
350 | { |
351 | return ref_compare( f_, rhs.f_ ) && l_ == rhs.l_; |
352 | } |
353 | }; |
354 | |
355 | // function_equal |
356 | |
357 | template<class R, class F, class L> bool function_equal( bind_t<R, F, L> const & a, bind_t<R, F, L> const & b ) |
358 | { |
359 | return a.compare(b); |
360 | } |
361 | |
362 | // add_value |
363 | |
364 | template< class T, int I > struct add_value_2 |
365 | { |
366 | typedef boost::arg<I> type; |
367 | }; |
368 | |
369 | template< class T > struct add_value_2< T, 0 > |
370 | { |
371 | typedef _bi::value< T > type; |
372 | }; |
373 | |
374 | template<class T> struct add_value |
375 | { |
376 | typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type; |
377 | }; |
378 | |
379 | template<class T> struct add_value< value<T> > |
380 | { |
381 | typedef _bi::value<T> type; |
382 | }; |
383 | |
384 | template<class T> struct add_value< reference_wrapper<T> > |
385 | { |
386 | typedef reference_wrapper<T> type; |
387 | }; |
388 | |
389 | template<int I> struct add_value< arg<I> > |
390 | { |
391 | typedef boost::arg<I> type; |
392 | }; |
393 | |
394 | template<int I> struct add_value< arg<I> (*) () > |
395 | { |
396 | typedef boost::arg<I> (*type) (); |
397 | }; |
398 | |
399 | template<class R, class F, class L> struct add_value< bind_t<R, F, L> > |
400 | { |
401 | typedef bind_t<R, F, L> type; |
402 | }; |
403 | |
404 | // list_av |
405 | |
406 | template<class... A> struct list_av |
407 | { |
408 | typedef list< typename add_value<A>::type... > type; |
409 | }; |
410 | |
411 | // operator! |
412 | |
413 | struct logical_not |
414 | { |
415 | template<class V> bool operator()(V const & v) const { return !v; } |
416 | }; |
417 | |
418 | template<class R, class F, class L> |
419 | bind_t< bool, logical_not, list< bind_t<R, F, L> > > |
420 | operator! (bind_t<R, F, L> const & f) |
421 | { |
422 | typedef list< bind_t<R, F, L> > list_type; |
423 | return bind_t<bool, logical_not, list_type> ( logical_not(), list_type(f) ); |
424 | } |
425 | |
426 | // relational operators |
427 | |
428 | #define BOOST_BIND_OPERATOR( op, name ) \ |
429 | \ |
430 | struct name \ |
431 | { \ |
432 | template<class V, class W> bool operator()(V const & v, W const & w) const { return v op w; } \ |
433 | }; \ |
434 | \ |
435 | template<class R, class F, class L, class A2> \ |
436 | bind_t< bool, name, list< bind_t<R, F, L>, typename add_value<A2>::type > > \ |
437 | operator op (bind_t<R, F, L> const & f, A2 a2) \ |
438 | { \ |
439 | typedef typename add_value<A2>::type B2; \ |
440 | typedef list< bind_t<R, F, L>, B2> list_type; \ |
441 | return bind_t<bool, name, list_type> ( name(), list_type(f, a2) ); \ |
442 | } |
443 | |
444 | BOOST_BIND_OPERATOR( ==, equal ) |
445 | BOOST_BIND_OPERATOR( !=, not_equal ) |
446 | |
447 | BOOST_BIND_OPERATOR( <, less ) |
448 | BOOST_BIND_OPERATOR( <=, less_equal ) |
449 | |
450 | BOOST_BIND_OPERATOR( >, greater ) |
451 | BOOST_BIND_OPERATOR( >=, greater_equal ) |
452 | |
453 | BOOST_BIND_OPERATOR( &&, logical_and ) |
454 | BOOST_BIND_OPERATOR( ||, logical_or ) |
455 | |
456 | #undef BOOST_BIND_OPERATOR |
457 | |
458 | // visit_each |
459 | |
460 | template<class V, class T> void visit_each( V & v, value<T> const & t, int ) |
461 | { |
462 | using boost::visit_each; |
463 | visit_each( v, t.get(), 0 ); |
464 | } |
465 | |
466 | template<class V, class R, class F, class L> void visit_each( V & v, bind_t<R, F, L> const & t, int ) |
467 | { |
468 | t.accept( v ); |
469 | } |
470 | |
471 | } // namespace _bi |
472 | |
473 | // is_bind_expression |
474 | |
475 | template< class T > struct is_bind_expression |
476 | { |
477 | enum _vt { value = 0 }; |
478 | }; |
479 | |
480 | template< class R, class F, class L > struct is_bind_expression< _bi::bind_t< R, F, L > > |
481 | { |
482 | enum _vt { value = 1 }; |
483 | }; |
484 | |
485 | // bind |
486 | |
487 | #ifndef BOOST_BIND |
488 | #define BOOST_BIND bind |
489 | #endif |
490 | |
491 | // generic function objects |
492 | |
493 | #if !BOOST_WORKAROUND(__GNUC__, < 6) |
494 | |
495 | template<class R, class F, class... A> |
496 | _bi::bind_t<R, F, typename _bi::list_av<A...>::type> |
497 | BOOST_BIND( F f, A... a ) |
498 | { |
499 | typedef typename _bi::list_av<A...>::type list_type; |
500 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a... ) ); |
501 | } |
502 | |
503 | #else |
504 | |
505 | // g++ 4.x (and some 5.x) consider boost::bind<void>( &X::f ) |
506 | // ambiguous if the variadic form above is used |
507 | |
508 | template<class R, class F> |
509 | _bi::bind_t<R, F, typename _bi::list_av<>::type> |
510 | BOOST_BIND( F f ) |
511 | { |
512 | typedef typename _bi::list_av<>::type list_type; |
513 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type() ); |
514 | } |
515 | |
516 | template<class R, class F, class A1> |
517 | _bi::bind_t<R, F, typename _bi::list_av<A1>::type> |
518 | BOOST_BIND( F f, A1 a1 ) |
519 | { |
520 | typedef typename _bi::list_av<A1>::type list_type; |
521 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1 ) ); |
522 | } |
523 | |
524 | template<class R, class F, class A1, class A2> |
525 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2>::type> |
526 | BOOST_BIND( F f, A1 a1, A2 a2 ) |
527 | { |
528 | typedef typename _bi::list_av<A1, A2>::type list_type; |
529 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2 ) ); |
530 | } |
531 | |
532 | template<class R, class F, class A1, class A2, class A3> |
533 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3>::type> |
534 | BOOST_BIND( F f, A1 a1, A2 a2, A3 a3 ) |
535 | { |
536 | typedef typename _bi::list_av<A1, A2, A3>::type list_type; |
537 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3 ) ); |
538 | } |
539 | |
540 | template<class R, class F, class A1, class A2, class A3, class A4> |
541 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4>::type> |
542 | BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4 ) |
543 | { |
544 | typedef typename _bi::list_av<A1, A2, A3, A4>::type list_type; |
545 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4 ) ); |
546 | } |
547 | |
548 | template<class R, class F, class A1, class A2, class A3, class A4, class A5> |
549 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5>::type> |
550 | BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ) |
551 | { |
552 | typedef typename _bi::list_av<A1, A2, A3, A4, A5>::type list_type; |
553 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5 ) ); |
554 | } |
555 | |
556 | template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6> |
557 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6>::type> |
558 | BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ) |
559 | { |
560 | typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6>::type list_type; |
561 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6 ) ); |
562 | } |
563 | |
564 | template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
565 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7>::type> |
566 | BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ) |
567 | { |
568 | typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
569 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6, a7 ) ); |
570 | } |
571 | |
572 | template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
573 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
574 | BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ) |
575 | { |
576 | typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
577 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6, a7, a8 ) ); |
578 | } |
579 | |
580 | template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
581 | _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
582 | BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ) |
583 | { |
584 | typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
585 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ); |
586 | } |
587 | |
588 | #endif |
589 | |
590 | // generic function objects, alternative syntax |
591 | |
592 | template<class R, class F, class... A> |
593 | _bi::bind_t<R, F, typename _bi::list_av<A...>::type> |
594 | BOOST_BIND( boost::type<R>, F f, A... a ) |
595 | { |
596 | typedef typename _bi::list_av<A...>::type list_type; |
597 | return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a... ) ); |
598 | } |
599 | |
600 | // adaptable function objects |
601 | |
602 | template<class F, class... A> |
603 | _bi::bind_t<_bi::unspecified, F, typename _bi::list_av<A...>::type> |
604 | BOOST_BIND( F f, A... a ) |
605 | { |
606 | typedef typename _bi::list_av<A...>::type list_type; |
607 | return _bi::bind_t<_bi::unspecified, F, list_type>( std::move(f), list_type( a... ) ); |
608 | } |
609 | |
610 | // function pointers |
611 | |
612 | #define BOOST_BIND_CC |
613 | #define BOOST_BIND_ST |
614 | #define BOOST_BIND_NOEXCEPT |
615 | |
616 | #include <boost/bind/detail/bind_cc.hpp> |
617 | |
618 | # if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) |
619 | # undef BOOST_BIND_NOEXCEPT |
620 | # define BOOST_BIND_NOEXCEPT noexcept |
621 | # include <boost/bind/detail/bind_cc.hpp> |
622 | # endif |
623 | |
624 | #undef BOOST_BIND_CC |
625 | #undef BOOST_BIND_ST |
626 | #undef BOOST_BIND_NOEXCEPT |
627 | |
628 | #if defined(BOOST_BIND_ENABLE_STDCALL) && !defined(_M_X64) |
629 | |
630 | #define BOOST_BIND_CC __stdcall |
631 | #define BOOST_BIND_ST |
632 | #define BOOST_BIND_NOEXCEPT |
633 | |
634 | #include <boost/bind/detail/bind_cc.hpp> |
635 | |
636 | #undef BOOST_BIND_CC |
637 | #undef BOOST_BIND_ST |
638 | #undef BOOST_BIND_NOEXCEPT |
639 | |
640 | #endif |
641 | |
642 | #if defined(BOOST_BIND_ENABLE_FASTCALL) && !defined(_M_X64) |
643 | |
644 | #define BOOST_BIND_CC __fastcall |
645 | #define BOOST_BIND_ST |
646 | #define BOOST_BIND_NOEXCEPT |
647 | |
648 | #include <boost/bind/detail/bind_cc.hpp> |
649 | |
650 | #undef BOOST_BIND_CC |
651 | #undef BOOST_BIND_ST |
652 | #undef BOOST_BIND_NOEXCEPT |
653 | |
654 | #endif |
655 | |
656 | #ifdef BOOST_BIND_ENABLE_PASCAL |
657 | |
658 | #define BOOST_BIND_ST pascal |
659 | #define BOOST_BIND_CC |
660 | #define BOOST_BIND_NOEXCEPT |
661 | |
662 | #include <boost/bind/detail/bind_cc.hpp> |
663 | |
664 | #undef BOOST_BIND_ST |
665 | #undef BOOST_BIND_CC |
666 | #undef BOOST_BIND_NOEXCEPT |
667 | |
668 | #endif |
669 | |
670 | // member function pointers |
671 | |
672 | #define BOOST_BIND_MF_NAME(X) X |
673 | #define BOOST_BIND_MF_CC |
674 | #define BOOST_BIND_MF_NOEXCEPT |
675 | |
676 | #include <boost/bind/detail/bind_mf_cc.hpp> |
677 | #include <boost/bind/detail/bind_mf2_cc.hpp> |
678 | |
679 | # if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) |
680 | # undef BOOST_BIND_MF_NOEXCEPT |
681 | # define BOOST_BIND_MF_NOEXCEPT noexcept |
682 | # include <boost/bind/detail/bind_mf_cc.hpp> |
683 | # include <boost/bind/detail/bind_mf2_cc.hpp> |
684 | # endif |
685 | |
686 | #undef BOOST_BIND_MF_NAME |
687 | #undef BOOST_BIND_MF_CC |
688 | #undef BOOST_BIND_MF_NOEXCEPT |
689 | |
690 | #if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64) |
691 | |
692 | #define BOOST_BIND_MF_NAME(X) X##_cdecl |
693 | #define BOOST_BIND_MF_CC __cdecl |
694 | #define BOOST_BIND_MF_NOEXCEPT |
695 | |
696 | #include <boost/bind/detail/bind_mf_cc.hpp> |
697 | #include <boost/bind/detail/bind_mf2_cc.hpp> |
698 | |
699 | #undef BOOST_BIND_MF_NAME |
700 | #undef BOOST_BIND_MF_CC |
701 | #undef BOOST_BIND_MF_NOEXCEPT |
702 | |
703 | #endif |
704 | |
705 | #if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64) |
706 | |
707 | #define BOOST_BIND_MF_NAME(X) X##_stdcall |
708 | #define BOOST_BIND_MF_CC __stdcall |
709 | #define BOOST_BIND_MF_NOEXCEPT |
710 | |
711 | #include <boost/bind/detail/bind_mf_cc.hpp> |
712 | #include <boost/bind/detail/bind_mf2_cc.hpp> |
713 | |
714 | #undef BOOST_BIND_MF_NAME |
715 | #undef BOOST_BIND_MF_CC |
716 | #undef BOOST_BIND_MF_NOEXCEPT |
717 | |
718 | #endif |
719 | |
720 | #if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64) |
721 | |
722 | #define BOOST_BIND_MF_NAME(X) X##_fastcall |
723 | #define BOOST_BIND_MF_CC __fastcall |
724 | #define BOOST_BIND_MF_NOEXCEPT |
725 | |
726 | #include <boost/bind/detail/bind_mf_cc.hpp> |
727 | #include <boost/bind/detail/bind_mf2_cc.hpp> |
728 | |
729 | #undef BOOST_BIND_MF_NAME |
730 | #undef BOOST_BIND_MF_CC |
731 | #undef BOOST_BIND_MF_NOEXCEPT |
732 | |
733 | #endif |
734 | |
735 | // data member pointers |
736 | |
737 | namespace _bi |
738 | { |
739 | |
740 | template< class Pm, int I > struct add_cref; |
741 | |
742 | template< class M, class T > struct add_cref< M T::*, 0 > |
743 | { |
744 | typedef M type; |
745 | }; |
746 | |
747 | template< class M, class T > struct add_cref< M T::*, 1 > |
748 | { |
749 | #ifdef BOOST_MSVC |
750 | #pragma warning(push) |
751 | #pragma warning(disable:4180) |
752 | #endif |
753 | typedef M const & type; |
754 | #ifdef BOOST_MSVC |
755 | #pragma warning(pop) |
756 | #endif |
757 | }; |
758 | |
759 | template< class R, class T > struct add_cref< R (T::*) (), 1 > |
760 | { |
761 | typedef void type; |
762 | }; |
763 | |
764 | template< class R, class T > struct add_cref< R (T::*) () const, 1 > |
765 | { |
766 | typedef void type; |
767 | }; |
768 | |
769 | #if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) |
770 | |
771 | template< class R, class T > struct add_cref< R (T::*) () const noexcept, 1 > |
772 | { |
773 | typedef void type; |
774 | }; |
775 | |
776 | #endif // __cpp_noexcept_function_type |
777 | |
778 | template<class R> struct isref |
779 | { |
780 | enum value_type { value = 0 }; |
781 | }; |
782 | |
783 | template<class R> struct isref< R& > |
784 | { |
785 | enum value_type { value = 1 }; |
786 | }; |
787 | |
788 | template<class R> struct isref< R* > |
789 | { |
790 | enum value_type { value = 1 }; |
791 | }; |
792 | |
793 | template<class Pm, class A1> struct dm_result |
794 | { |
795 | typedef typename add_cref< Pm, 1 >::type type; |
796 | }; |
797 | |
798 | template<class Pm, class R, class F, class L> struct dm_result< Pm, bind_t<R, F, L> > |
799 | { |
800 | typedef typename bind_t<R, F, L>::result_type result_type; |
801 | typedef typename add_cref< Pm, isref< result_type >::value >::type type; |
802 | }; |
803 | |
804 | } // namespace _bi |
805 | |
806 | template< class A1, class M, class T > |
807 | |
808 | _bi::bind_t< |
809 | typename _bi::dm_result< M T::*, A1 >::type, |
810 | _mfi::dm<M, T>, |
811 | typename _bi::list_av<A1>::type |
812 | > |
813 | |
814 | BOOST_BIND( M T::*f, A1 a1 ) |
815 | { |
816 | typedef typename _bi::dm_result< M T::*, A1 >::type result_type; |
817 | typedef _mfi::dm<M, T> F; |
818 | typedef typename _bi::list_av<A1>::type list_type; |
819 | return _bi::bind_t< result_type, F, list_type >( F( f ), list_type( a1 ) ); |
820 | } |
821 | |
822 | } // namespace boost |
823 | |
824 | #ifndef BOOST_BIND_NO_PLACEHOLDERS |
825 | |
826 | # include <boost/bind/placeholders.hpp> |
827 | |
828 | #endif |
829 | |
830 | #ifdef BOOST_MSVC |
831 | # pragma warning(default: 4512) // assignment operator could not be generated |
832 | # pragma warning(pop) |
833 | #endif |
834 | |
835 | #endif // #ifndef BOOST_BIND_BIND_HPP_INCLUDED |
836 | |