Line data Source code
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 2920 : value(T const & t): t_(t) {}
90 :
91 1460 : 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 21754 : static inline F & unwrap( F & f, long )
120 : {
121 21754 : 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 43508 : 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 21170 : 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 21170 : 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 584 : template<class F, class A2, std::size_t... I> void call_impl( type<void>, F & f, A2 & a2, _bi::index_sequence<I...> )
191 : {
192 584 : unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... );
193 584 : }
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 21754 : template<class R, class F, class A2> R operator()( type<R>, F & f, A2 & a2 )
207 : {
208 21754 : 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 43508 : explicit rrlist( A&... a ): data_( a... ) {}
271 : template<class... B> explicit rrlist( rrlist<B...> const& r ): data_( r.data_ ) {}
272 :
273 21170 : template<int I> typename std::tuple_element<I-1, args_type>::type&& operator[] ( boost::arg<I> ) const
274 : {
275 21170 : 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 1460 : 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 21170 : 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 43508 : bind_t( F f, L const & l ): f_( std::move(f) ), l_( l ) {}
315 :
316 : //
317 :
318 21754 : template<class... A> result_type operator()( A&&... a )
319 : {
320 21754 : rrlist<A...> a2( a... );
321 21754 : 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 21608 : BOOST_BIND( F f, A... a )
605 : {
606 : typedef typename _bi::list_av<A...>::type list_type;
607 21608 : return _bi::bind_t<_bi::unspecified, F, list_type>( std::move(f), list_type( a... ) );
608 0 : }
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 M, int I> struct add_cref;
741 :
742 : template<class M> struct add_cref<M, 0>
743 : {
744 : typedef M type;
745 : };
746 :
747 : template<class M> struct add_cref<M, 1>
748 : {
749 : typedef M const& type;
750 : };
751 :
752 : template<class R> struct isref
753 : {
754 : enum value_type { value = 0 };
755 : };
756 :
757 : template<class R> struct isref< R& >
758 : {
759 : enum value_type { value = 1 };
760 : };
761 :
762 : template<class R> struct isref< R* >
763 : {
764 : enum value_type { value = 1 };
765 : };
766 :
767 : template<class M, class A1, bool fn = std::is_function<M>::value> struct dm_result
768 : {
769 : };
770 :
771 : template<class M, class A1> struct dm_result<M, A1, false>
772 : {
773 : typedef typename add_cref< M, 1 >::type type;
774 : };
775 :
776 : template<class M, class R, class F, class L> struct dm_result<M, bind_t<R, F, L>, false>
777 : {
778 : typedef typename bind_t<R, F, L>::result_type result_type;
779 : typedef typename add_cref< M, isref< result_type >::value >::type type;
780 : };
781 :
782 : } // namespace _bi
783 :
784 : template<class A1, class M, class T>
785 :
786 : _bi::bind_t<
787 : typename _bi::dm_result<M, A1>::type,
788 : _mfi::dm<M, T>,
789 : typename _bi::list_av<A1>::type
790 : >
791 :
792 : BOOST_BIND( M T::*f, A1 a1 )
793 : {
794 : typedef typename _bi::dm_result<M, A1>::type result_type;
795 : typedef _mfi::dm<M, T> F;
796 : typedef typename _bi::list_av<A1>::type list_type;
797 : return _bi::bind_t< result_type, F, list_type >( F( f ), list_type( a1 ) );
798 : }
799 :
800 : } // namespace boost
801 :
802 : #ifndef BOOST_BIND_NO_PLACEHOLDERS
803 :
804 : # include <boost/bind/placeholders.hpp>
805 :
806 : #endif
807 :
808 : #ifdef BOOST_MSVC
809 : # pragma warning(default: 4512) // assignment operator could not be generated
810 : # pragma warning(pop)
811 : #endif
812 :
813 : #endif // #ifndef BOOST_BIND_BIND_HPP_INCLUDED
|