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
44namespace boost
45{
46
47template<class T> class weak_ptr;
48
49namespace _bi // implementation details
50{
51
52// ref_compare
53
54template<class T> bool ref_compare( T const & a, T const & b )
55{
56 return a == b;
57}
58
59template<int I> bool ref_compare( arg<I> const &, arg<I> const & )
60{
61 return true;
62}
63
64template<int I> bool ref_compare( arg<I> (*) (), arg<I> (*) () )
65{
66 return true;
67}
68
69template<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
76template<class R, class F, class L> class bind_t;
77
78template<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
85template<class T> class value
86{
87public:
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
99private:
100
101 T t_;
102};
103
104// ref_compare for weak_ptr
105
106template<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
113template<class T> class type {};
114
115// unwrap
116
117template<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
137template<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
149struct 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
161struct logical_and;
162struct logical_or;
163
164template<class... A> class list
165{
166private:
167
168 typedef std::tuple<A...> data_type;
169 data_type data_;
170
171public:
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
257template<class... A> class rrlist
258{
259private:
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
268public:
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
302template<class R, class F, class L> class bind_t
303{
304private:
305
306 F f_;
307 L l_;
308
309public:
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
357template<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
364template< class T, int I > struct add_value_2
365{
366 typedef boost::arg<I> type;
367};
368
369template< class T > struct add_value_2< T, 0 >
370{
371 typedef _bi::value< T > type;
372};
373
374template<class T> struct add_value
375{
376 typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type;
377};
378
379template<class T> struct add_value< value<T> >
380{
381 typedef _bi::value<T> type;
382};
383
384template<class T> struct add_value< reference_wrapper<T> >
385{
386 typedef reference_wrapper<T> type;
387};
388
389template<int I> struct add_value< arg<I> >
390{
391 typedef boost::arg<I> type;
392};
393
394template<int I> struct add_value< arg<I> (*) () >
395{
396 typedef boost::arg<I> (*type) ();
397};
398
399template<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
406template<class... A> struct list_av
407{
408 typedef list< typename add_value<A>::type... > type;
409};
410
411// operator!
412
413struct logical_not
414{
415 template<class V> bool operator()(V const & v) const { return !v; }
416};
417
418template<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\
430struct name \
431{ \
432 template<class V, class W> bool operator()(V const & v, W const & w) const { return v op w; } \
433}; \
434 \
435template<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
444BOOST_BIND_OPERATOR( ==, equal )
445BOOST_BIND_OPERATOR( !=, not_equal )
446
447BOOST_BIND_OPERATOR( <, less )
448BOOST_BIND_OPERATOR( <=, less_equal )
449
450BOOST_BIND_OPERATOR( >, greater )
451BOOST_BIND_OPERATOR( >=, greater_equal )
452
453BOOST_BIND_OPERATOR( &&, logical_and )
454BOOST_BIND_OPERATOR( ||, logical_or )
455
456#undef BOOST_BIND_OPERATOR
457
458// visit_each
459
460template<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
466template<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
475template< class T > struct is_bind_expression
476{
477 enum _vt { value = 0 };
478};
479
480template< 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
495template<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
508template<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
516template<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
524template<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
532template<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
540template<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
548template<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
556template<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
564template<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
572template<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
580template<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
592template<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
602template<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
737namespace _bi
738{
739
740template< class Pm, int I > struct add_cref;
741
742template< class M, class T > struct add_cref< M T::*, 0 >
743{
744 typedef M type;
745};
746
747template< 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
759template< class R, class T > struct add_cref< R (T::*) (), 1 >
760{
761 typedef void type;
762};
763
764template< 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
771template< 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
778template<class R> struct isref
779{
780 enum value_type { value = 0 };
781};
782
783template<class R> struct isref< R& >
784{
785 enum value_type { value = 1 };
786};
787
788template<class R> struct isref< R* >
789{
790 enum value_type { value = 1 };
791};
792
793template<class Pm, class A1> struct dm_result
794{
795 typedef typename add_cref< Pm, 1 >::type type;
796};
797
798template<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
806template< 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
814BOOST_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

source code of boost/libs/bind/include/boost/bind/bind.hpp