bind.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. #ifndef BOOST_BIND_BIND_HPP_INCLUDED
  2. #define BOOST_BIND_BIND_HPP_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. //
  8. // bind.hpp - binds function objects to arguments
  9. //
  10. // Copyright 2001-2005, 2024 Peter Dimov
  11. // Copyright 2001 David Abrahams
  12. //
  13. // Distributed under the Boost Software License, Version 1.0. (See
  14. // accompanying file LICENSE_1_0.txt or copy at
  15. // http://www.boost.org/LICENSE_1_0.txt)
  16. //
  17. // See http://www.boost.org/libs/bind for documentation.
  18. //
  19. #include <boost/bind/mem_fn.hpp>
  20. #include <boost/bind/arg.hpp>
  21. #include <boost/bind/std_placeholders.hpp>
  22. #include <boost/bind/detail/result_traits.hpp>
  23. #include <boost/bind/detail/tuple_for_each.hpp>
  24. #include <boost/bind/detail/integer_sequence.hpp>
  25. #include <boost/visit_each.hpp>
  26. #include <boost/is_placeholder.hpp>
  27. #include <boost/type.hpp>
  28. #include <boost/core/ref.hpp>
  29. #include <boost/config.hpp>
  30. #include <boost/config/workaround.hpp>
  31. #include <utility>
  32. #include <type_traits>
  33. #include <tuple>
  34. #ifdef BOOST_MSVC
  35. # pragma warning(push)
  36. # pragma warning(disable: 4512) // assignment operator could not be generated
  37. #endif
  38. namespace boost
  39. {
  40. template<class T> class weak_ptr;
  41. namespace _bi // implementation details
  42. {
  43. // ref_compare
  44. template<class T> bool ref_compare( T const & a, T const & b )
  45. {
  46. return a == b;
  47. }
  48. template<int I> bool ref_compare( arg<I> const &, arg<I> const & )
  49. {
  50. return true;
  51. }
  52. template<int I> bool ref_compare( arg<I> (*) (), arg<I> (*) () )
  53. {
  54. return true;
  55. }
  56. template<class T> bool ref_compare( reference_wrapper<T> const & a, reference_wrapper<T> const & b )
  57. {
  58. return a.get_pointer() == b.get_pointer();
  59. }
  60. // bind_t forward declaration for listN
  61. template<class R, class F, class L> class bind_t;
  62. template<class R, class F, class L> bool ref_compare( bind_t<R, F, L> const & a, bind_t<R, F, L> const & b )
  63. {
  64. return a.compare( b );
  65. }
  66. // value
  67. template<class T> class value
  68. {
  69. public:
  70. value(T const & t): t_(t) {}
  71. T & get() { return t_; }
  72. T const & get() const { return t_; }
  73. bool operator==(value const & rhs) const
  74. {
  75. return t_ == rhs.t_;
  76. }
  77. private:
  78. T t_;
  79. };
  80. // ref_compare for weak_ptr
  81. template<class T> bool ref_compare( value< weak_ptr<T> > const & a, value< weak_ptr<T> > const & b )
  82. {
  83. return !(a.get() < b.get()) && !(b.get() < a.get());
  84. }
  85. // type
  86. template<class T> class type {};
  87. // unwrap
  88. template<class F> struct unwrapper
  89. {
  90. static inline F & unwrap( F & f, long )
  91. {
  92. return f;
  93. }
  94. template<class F2> static inline F2 & unwrap( reference_wrapper<F2> rf, int )
  95. {
  96. return rf.get();
  97. }
  98. template<class R, class T> static inline _mfi::dm<R, T> unwrap( R T::* pm, int )
  99. {
  100. return _mfi::dm<R, T>( pm );
  101. }
  102. };
  103. // list
  104. template<class V> struct accept_lambda
  105. {
  106. V& v_;
  107. explicit accept_lambda( V& v ): v_( v ) {}
  108. template<class A> void operator()( A& a ) const
  109. {
  110. visit_each( v_, a, 0 );
  111. }
  112. };
  113. struct equal_lambda
  114. {
  115. bool result;
  116. equal_lambda(): result( true ) {}
  117. template<class A1, class A2> void operator()( A1& a1, A2& a2 )
  118. {
  119. result = result && ref_compare( a1, a2 );
  120. }
  121. };
  122. struct logical_and;
  123. struct logical_or;
  124. template<class... A> class list
  125. {
  126. private:
  127. typedef std::tuple<A...> data_type;
  128. data_type data_;
  129. public:
  130. list( A... a ): data_( a... ) {}
  131. #if defined(BOOST_MSVC)
  132. # pragma warning( push )
  133. # pragma warning( disable: 4100 ) // unreferenced formal parameter 'a2'
  134. #endif
  135. template<class R, class F, class A2, std::size_t... I> R call_impl( type<R>, F & f, A2 & a2, _bi::index_sequence<I...> )
  136. {
  137. return unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... );
  138. }
  139. 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
  140. {
  141. return unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... );
  142. }
  143. template<class F, class A2, std::size_t... I> void call_impl( type<void>, F & f, A2 & a2, _bi::index_sequence<I...> )
  144. {
  145. unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... );
  146. }
  147. template<class F, class A2, std::size_t... I> void call_impl( type<void>, F & f, A2 & a2, _bi::index_sequence<I...> ) const
  148. {
  149. unwrapper<F>::unwrap( f, 0 )( a2[ std::get<I>( data_ ) ]... );
  150. }
  151. #if defined(BOOST_MSVC)
  152. # pragma warning( pop )
  153. #endif
  154. //
  155. template<class R, class F, class A2> R operator()( type<R>, F & f, A2 & a2 )
  156. {
  157. return call_impl( type<R>(), f, a2, _bi::index_sequence_for<A...>() );
  158. }
  159. template<class R, class F, class A2> R operator()( type<R>, F & f, A2 & a2 ) const
  160. {
  161. return call_impl( type<R>(), f, a2, _bi::index_sequence_for<A...>() );
  162. }
  163. //
  164. template<class A2> bool operator()( type<bool>, logical_and & /*f*/, A2 & a2 )
  165. {
  166. static_assert( sizeof...(A) == 2, "operator&& must have two arguments" );
  167. return a2[ std::get<0>( data_ ) ] && a2[ std::get<1>( data_ ) ];
  168. }
  169. template<class A2> bool operator()( type<bool>, logical_and const & /*f*/, A2 & a2 ) const
  170. {
  171. static_assert( sizeof...(A) == 2, "operator&& must have two arguments" );
  172. return a2[ std::get<0>( data_ ) ] && a2[ std::get<1>( data_ ) ];
  173. }
  174. template<class A2> bool operator()( type<bool>, logical_or & /*f*/, A2 & a2 )
  175. {
  176. static_assert( sizeof...(A) == 2, "operator|| must have two arguments" );
  177. return a2[ std::get<0>( data_ ) ] || a2[ std::get<1>( data_ ) ];
  178. }
  179. template<class A2> bool operator()( type<bool>, logical_or const & /*f*/, A2 & a2 ) const
  180. {
  181. static_assert( sizeof...(A) == 2, "operator|| must have two arguments" );
  182. return a2[ std::get<0>( data_ ) ] || a2[ std::get<1>( data_ ) ];
  183. }
  184. //
  185. template<class V> void accept( V & v ) const
  186. {
  187. _bi::tuple_for_each( accept_lambda<V>( v ), data_ );
  188. }
  189. bool operator==( list const & rhs ) const
  190. {
  191. return _bi::tuple_for_each( equal_lambda(), data_, rhs.data_ ).result;
  192. }
  193. };
  194. // bind_t
  195. template<class... A> class rrlist
  196. {
  197. private:
  198. using args_type = std::tuple<A...>;
  199. using data_type = std::tuple<A&...>;
  200. data_type data_;
  201. template<class...> friend class rrlist;
  202. public:
  203. explicit rrlist( A&... a ): data_( a... ) {}
  204. template<class... B> explicit rrlist( rrlist<B...> const& r ): data_( r.data_ ) {}
  205. template<int I> typename std::tuple_element<I-1, args_type>::type&& operator[] ( boost::arg<I> ) const
  206. {
  207. return std::forward<typename std::tuple_element<I-1, args_type>::type>( std::get<I-1>( data_ ) );
  208. }
  209. template<int I> typename std::tuple_element<I-1, args_type>::type&& operator[] ( boost::arg<I>(*)() ) const
  210. {
  211. return std::forward<typename std::tuple_element<I-1, args_type>::type>( std::get<I-1>( data_ ) );
  212. }
  213. template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
  214. template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
  215. template<class T> T & operator[] ( reference_wrapper<T> const & v ) const { return v.get(); }
  216. template<class R, class F, class L> typename result_traits<R, F>::type operator[] ( bind_t<R, F, L> & b ) const
  217. {
  218. rrlist<A&...> a2( *this );
  219. return b.eval( a2 );
  220. }
  221. template<class R, class F, class L> typename result_traits<R, F>::type operator[] ( bind_t<R, F, L> const & b ) const
  222. {
  223. rrlist<A&...> a2( *this );
  224. return b.eval( a2 );
  225. }
  226. };
  227. template<class R, class F, class L> class bind_t
  228. {
  229. private:
  230. F f_;
  231. L l_;
  232. public:
  233. typedef typename result_traits<R, F>::type result_type;
  234. typedef bind_t this_type;
  235. bind_t( F f, L const & l ): f_( std::move(f) ), l_( l ) {}
  236. //
  237. template<class... A> result_type operator()( A&&... a )
  238. {
  239. rrlist<A...> a2( a... );
  240. return l_( type<result_type>(), f_, a2 );
  241. }
  242. template<class... A> result_type operator()( A&&... a ) const
  243. {
  244. rrlist<A...> a2( a... );
  245. return l_( type<result_type>(), f_, a2 );
  246. }
  247. //
  248. template<class A> result_type eval( A & a )
  249. {
  250. return l_( type<result_type>(), f_, a );
  251. }
  252. template<class A> result_type eval( A & a ) const
  253. {
  254. return l_( type<result_type>(), f_, a );
  255. }
  256. template<class V> void accept( V & v ) const
  257. {
  258. using boost::visit_each;
  259. visit_each( v, f_, 0 );
  260. l_.accept( v );
  261. }
  262. bool compare( this_type const & rhs ) const
  263. {
  264. return ref_compare( f_, rhs.f_ ) && l_ == rhs.l_;
  265. }
  266. };
  267. // function_equal
  268. template<class R, class F, class L> bool function_equal( bind_t<R, F, L> const & a, bind_t<R, F, L> const & b )
  269. {
  270. return a.compare(b);
  271. }
  272. // add_value
  273. template< class T, int I > struct add_value_2
  274. {
  275. typedef boost::arg<I> type;
  276. };
  277. template< class T > struct add_value_2< T, 0 >
  278. {
  279. typedef _bi::value< T > type;
  280. };
  281. template<class T> struct add_value
  282. {
  283. typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type;
  284. };
  285. template<class T> struct add_value< value<T> >
  286. {
  287. typedef _bi::value<T> type;
  288. };
  289. template<class T> struct add_value< reference_wrapper<T> >
  290. {
  291. typedef reference_wrapper<T> type;
  292. };
  293. template<int I> struct add_value< arg<I> >
  294. {
  295. typedef boost::arg<I> type;
  296. };
  297. template<int I> struct add_value< arg<I> (*) () >
  298. {
  299. typedef boost::arg<I> (*type) ();
  300. };
  301. template<class R, class F, class L> struct add_value< bind_t<R, F, L> >
  302. {
  303. typedef bind_t<R, F, L> type;
  304. };
  305. // list_av
  306. template<class... A> struct list_av
  307. {
  308. typedef list< typename add_value<A>::type... > type;
  309. };
  310. // operator!
  311. struct logical_not
  312. {
  313. template<class V> bool operator()(V const & v) const { return !v; }
  314. };
  315. template<class R, class F, class L>
  316. bind_t< bool, logical_not, list< bind_t<R, F, L> > >
  317. operator! (bind_t<R, F, L> const & f)
  318. {
  319. typedef list< bind_t<R, F, L> > list_type;
  320. return bind_t<bool, logical_not, list_type> ( logical_not(), list_type(f) );
  321. }
  322. // relational operators
  323. #define BOOST_BIND_OPERATOR( op, name ) \
  324. \
  325. struct name \
  326. { \
  327. template<class V, class W> bool operator()(V const & v, W const & w) const { return v op w; } \
  328. }; \
  329. \
  330. template<class R, class F, class L, class A2> \
  331. bind_t< bool, name, list< bind_t<R, F, L>, typename add_value<A2>::type > > \
  332. operator op (bind_t<R, F, L> const & f, A2 a2) \
  333. { \
  334. typedef typename add_value<A2>::type B2; \
  335. typedef list< bind_t<R, F, L>, B2> list_type; \
  336. return bind_t<bool, name, list_type> ( name(), list_type(f, a2) ); \
  337. }
  338. BOOST_BIND_OPERATOR( ==, equal )
  339. BOOST_BIND_OPERATOR( !=, not_equal )
  340. BOOST_BIND_OPERATOR( <, less )
  341. BOOST_BIND_OPERATOR( <=, less_equal )
  342. BOOST_BIND_OPERATOR( >, greater )
  343. BOOST_BIND_OPERATOR( >=, greater_equal )
  344. BOOST_BIND_OPERATOR( &&, logical_and )
  345. BOOST_BIND_OPERATOR( ||, logical_or )
  346. #undef BOOST_BIND_OPERATOR
  347. // visit_each
  348. template<class V, class T> void visit_each( V & v, value<T> const & t, int )
  349. {
  350. using boost::visit_each;
  351. visit_each( v, t.get(), 0 );
  352. }
  353. template<class V, class R, class F, class L> void visit_each( V & v, bind_t<R, F, L> const & t, int )
  354. {
  355. t.accept( v );
  356. }
  357. } // namespace _bi
  358. // is_bind_expression
  359. template< class T > struct is_bind_expression
  360. {
  361. enum _vt { value = 0 };
  362. };
  363. template< class R, class F, class L > struct is_bind_expression< _bi::bind_t< R, F, L > >
  364. {
  365. enum _vt { value = 1 };
  366. };
  367. // bind
  368. #ifndef BOOST_BIND
  369. #define BOOST_BIND bind
  370. #endif
  371. // generic function objects
  372. #if !BOOST_WORKAROUND(__GNUC__, < 6)
  373. template<class R, class F, class... A>
  374. _bi::bind_t<R, F, typename _bi::list_av<A...>::type>
  375. BOOST_BIND( F f, A... a )
  376. {
  377. typedef typename _bi::list_av<A...>::type list_type;
  378. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a... ) );
  379. }
  380. #else
  381. // g++ 4.x (and some 5.x) consider boost::bind<void>( &X::f )
  382. // ambiguous if the variadic form above is used
  383. template<class R, class F>
  384. _bi::bind_t<R, F, typename _bi::list_av<>::type>
  385. BOOST_BIND( F f )
  386. {
  387. typedef typename _bi::list_av<>::type list_type;
  388. return _bi::bind_t<R, F, list_type>( std::move(f), list_type() );
  389. }
  390. template<class R, class F, class A1>
  391. _bi::bind_t<R, F, typename _bi::list_av<A1>::type>
  392. BOOST_BIND( F f, A1 a1 )
  393. {
  394. typedef typename _bi::list_av<A1>::type list_type;
  395. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1 ) );
  396. }
  397. template<class R, class F, class A1, class A2>
  398. _bi::bind_t<R, F, typename _bi::list_av<A1, A2>::type>
  399. BOOST_BIND( F f, A1 a1, A2 a2 )
  400. {
  401. typedef typename _bi::list_av<A1, A2>::type list_type;
  402. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2 ) );
  403. }
  404. template<class R, class F, class A1, class A2, class A3>
  405. _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3>::type>
  406. BOOST_BIND( F f, A1 a1, A2 a2, A3 a3 )
  407. {
  408. typedef typename _bi::list_av<A1, A2, A3>::type list_type;
  409. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3 ) );
  410. }
  411. template<class R, class F, class A1, class A2, class A3, class A4>
  412. _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4>::type>
  413. BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4 )
  414. {
  415. typedef typename _bi::list_av<A1, A2, A3, A4>::type list_type;
  416. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4 ) );
  417. }
  418. template<class R, class F, class A1, class A2, class A3, class A4, class A5>
  419. _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5>::type>
  420. BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 )
  421. {
  422. typedef typename _bi::list_av<A1, A2, A3, A4, A5>::type list_type;
  423. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5 ) );
  424. }
  425. template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6>
  426. _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6>::type>
  427. BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 )
  428. {
  429. typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6>::type list_type;
  430. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6 ) );
  431. }
  432. template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
  433. _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7>::type>
  434. BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 )
  435. {
  436. typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7>::type list_type;
  437. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6, a7 ) );
  438. }
  439. template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
  440. _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8>::type>
  441. BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 )
  442. {
  443. typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
  444. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6, a7, a8 ) );
  445. }
  446. template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
  447. _bi::bind_t<R, F, typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
  448. BOOST_BIND( F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 )
  449. {
  450. typedef typename _bi::list_av<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
  451. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a1, a2, a3, a4, a5, a6, a7, a8, a9 ) );
  452. }
  453. #endif
  454. // generic function objects, alternative syntax
  455. template<class R, class F, class... A>
  456. _bi::bind_t<R, F, typename _bi::list_av<A...>::type>
  457. BOOST_BIND( boost::type<R>, F f, A... a )
  458. {
  459. typedef typename _bi::list_av<A...>::type list_type;
  460. return _bi::bind_t<R, F, list_type>( std::move(f), list_type( a... ) );
  461. }
  462. // adaptable function objects
  463. template<class F, class... A>
  464. _bi::bind_t<_bi::unspecified, F, typename _bi::list_av<A...>::type>
  465. BOOST_BIND( F f, A... a )
  466. {
  467. typedef typename _bi::list_av<A...>::type list_type;
  468. return _bi::bind_t<_bi::unspecified, F, list_type>( std::move(f), list_type( a... ) );
  469. }
  470. // function pointers
  471. #define BOOST_BIND_CC
  472. #define BOOST_BIND_ST
  473. #define BOOST_BIND_NOEXCEPT
  474. #include <boost/bind/detail/bind_cc.hpp>
  475. # if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
  476. # undef BOOST_BIND_NOEXCEPT
  477. # define BOOST_BIND_NOEXCEPT noexcept
  478. # include <boost/bind/detail/bind_cc.hpp>
  479. # endif
  480. #undef BOOST_BIND_CC
  481. #undef BOOST_BIND_ST
  482. #undef BOOST_BIND_NOEXCEPT
  483. #if defined(BOOST_BIND_ENABLE_STDCALL) && !defined(_M_X64)
  484. #define BOOST_BIND_CC __stdcall
  485. #define BOOST_BIND_ST
  486. #define BOOST_BIND_NOEXCEPT
  487. #include <boost/bind/detail/bind_cc.hpp>
  488. #undef BOOST_BIND_CC
  489. #undef BOOST_BIND_ST
  490. #undef BOOST_BIND_NOEXCEPT
  491. #endif
  492. #if defined(BOOST_BIND_ENABLE_FASTCALL) && !defined(_M_X64)
  493. #define BOOST_BIND_CC __fastcall
  494. #define BOOST_BIND_ST
  495. #define BOOST_BIND_NOEXCEPT
  496. #include <boost/bind/detail/bind_cc.hpp>
  497. #undef BOOST_BIND_CC
  498. #undef BOOST_BIND_ST
  499. #undef BOOST_BIND_NOEXCEPT
  500. #endif
  501. #ifdef BOOST_BIND_ENABLE_PASCAL
  502. #define BOOST_BIND_ST pascal
  503. #define BOOST_BIND_CC
  504. #define BOOST_BIND_NOEXCEPT
  505. #include <boost/bind/detail/bind_cc.hpp>
  506. #undef BOOST_BIND_ST
  507. #undef BOOST_BIND_CC
  508. #undef BOOST_BIND_NOEXCEPT
  509. #endif
  510. // member function pointers
  511. #define BOOST_BIND_MF_NAME(X) X
  512. #define BOOST_BIND_MF_CC
  513. #define BOOST_BIND_MF_NOEXCEPT
  514. #include <boost/bind/detail/bind_mf_cc.hpp>
  515. #include <boost/bind/detail/bind_mf2_cc.hpp>
  516. # if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
  517. # undef BOOST_BIND_MF_NOEXCEPT
  518. # define BOOST_BIND_MF_NOEXCEPT noexcept
  519. # include <boost/bind/detail/bind_mf_cc.hpp>
  520. # include <boost/bind/detail/bind_mf2_cc.hpp>
  521. # endif
  522. #undef BOOST_BIND_MF_NAME
  523. #undef BOOST_BIND_MF_CC
  524. #undef BOOST_BIND_MF_NOEXCEPT
  525. #if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64)
  526. #define BOOST_BIND_MF_NAME(X) X##_cdecl
  527. #define BOOST_BIND_MF_CC __cdecl
  528. #define BOOST_BIND_MF_NOEXCEPT
  529. #include <boost/bind/detail/bind_mf_cc.hpp>
  530. #include <boost/bind/detail/bind_mf2_cc.hpp>
  531. #undef BOOST_BIND_MF_NAME
  532. #undef BOOST_BIND_MF_CC
  533. #undef BOOST_BIND_MF_NOEXCEPT
  534. #endif
  535. #if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64)
  536. #define BOOST_BIND_MF_NAME(X) X##_stdcall
  537. #define BOOST_BIND_MF_CC __stdcall
  538. #define BOOST_BIND_MF_NOEXCEPT
  539. #include <boost/bind/detail/bind_mf_cc.hpp>
  540. #include <boost/bind/detail/bind_mf2_cc.hpp>
  541. #undef BOOST_BIND_MF_NAME
  542. #undef BOOST_BIND_MF_CC
  543. #undef BOOST_BIND_MF_NOEXCEPT
  544. #endif
  545. #if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64)
  546. #define BOOST_BIND_MF_NAME(X) X##_fastcall
  547. #define BOOST_BIND_MF_CC __fastcall
  548. #define BOOST_BIND_MF_NOEXCEPT
  549. #include <boost/bind/detail/bind_mf_cc.hpp>
  550. #include <boost/bind/detail/bind_mf2_cc.hpp>
  551. #undef BOOST_BIND_MF_NAME
  552. #undef BOOST_BIND_MF_CC
  553. #undef BOOST_BIND_MF_NOEXCEPT
  554. #endif
  555. // data member pointers
  556. namespace _bi
  557. {
  558. template< class Pm, int I > struct add_cref;
  559. template< class M, class T > struct add_cref< M T::*, 0 >
  560. {
  561. typedef M type;
  562. };
  563. template< class M, class T > struct add_cref< M T::*, 1 >
  564. {
  565. #ifdef BOOST_MSVC
  566. #pragma warning(push)
  567. #pragma warning(disable:4180)
  568. #endif
  569. typedef M const & type;
  570. #ifdef BOOST_MSVC
  571. #pragma warning(pop)
  572. #endif
  573. };
  574. template< class R, class T > struct add_cref< R (T::*) (), 1 >
  575. {
  576. typedef void type;
  577. };
  578. template< class R, class T > struct add_cref< R (T::*) () const, 1 >
  579. {
  580. typedef void type;
  581. };
  582. #if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
  583. template< class R, class T > struct add_cref< R (T::*) () const noexcept, 1 >
  584. {
  585. typedef void type;
  586. };
  587. #endif // __cpp_noexcept_function_type
  588. template<class R> struct isref
  589. {
  590. enum value_type { value = 0 };
  591. };
  592. template<class R> struct isref< R& >
  593. {
  594. enum value_type { value = 1 };
  595. };
  596. template<class R> struct isref< R* >
  597. {
  598. enum value_type { value = 1 };
  599. };
  600. template<class Pm, class A1> struct dm_result
  601. {
  602. typedef typename add_cref< Pm, 1 >::type type;
  603. };
  604. template<class Pm, class R, class F, class L> struct dm_result< Pm, bind_t<R, F, L> >
  605. {
  606. typedef typename bind_t<R, F, L>::result_type result_type;
  607. typedef typename add_cref< Pm, isref< result_type >::value >::type type;
  608. };
  609. } // namespace _bi
  610. template< class A1, class M, class T >
  611. _bi::bind_t<
  612. typename _bi::dm_result< M T::*, A1 >::type,
  613. _mfi::dm<M, T>,
  614. typename _bi::list_av<A1>::type
  615. >
  616. BOOST_BIND( M T::*f, A1 a1 )
  617. {
  618. typedef typename _bi::dm_result< M T::*, A1 >::type result_type;
  619. typedef _mfi::dm<M, T> F;
  620. typedef typename _bi::list_av<A1>::type list_type;
  621. return _bi::bind_t< result_type, F, list_type >( F( f ), list_type( a1 ) );
  622. }
  623. } // namespace boost
  624. #ifndef BOOST_BIND_NO_PLACEHOLDERS
  625. # include <boost/bind/placeholders.hpp>
  626. #endif
  627. #ifdef BOOST_MSVC
  628. # pragma warning(default: 4512) // assignment operator could not be generated
  629. # pragma warning(pop)
  630. #endif
  631. #endif // #ifndef BOOST_BIND_BIND_HPP_INCLUDED