mem_fn.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED
  2. #define BOOST_BIND_MEM_FN_HPP_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. //
  8. // mem_fn.hpp - a generalization of std::mem_fun[_ref]
  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/mem_fn.html for documentation.
  18. //
  19. #include <boost/get_pointer.hpp>
  20. #include <boost/config.hpp>
  21. #include <boost/config/workaround.hpp>
  22. #include <type_traits>
  23. namespace boost
  24. {
  25. namespace _mfi
  26. {
  27. template<class T> struct remove_cvref: std::remove_cv< typename std::remove_reference<T>::type >
  28. {
  29. };
  30. template<class Pm, class R, class T, class... A> class mf
  31. {
  32. public:
  33. typedef R result_type;
  34. private:
  35. Pm pm_;
  36. public:
  37. mf( Pm pm ): pm_( pm ) {}
  38. template<class U,
  39. class Ud = typename _mfi::remove_cvref<U>::type,
  40. class En = typename std::enable_if<
  41. std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value
  42. >::type
  43. >
  44. R operator()( U&& u, A... a ) const
  45. {
  46. return (std::forward<U>( u ).*pm_)( std::forward<A>( a )... );
  47. }
  48. template<class U,
  49. class Ud = typename _mfi::remove_cvref<U>::type,
  50. class E1 = void,
  51. class En = typename std::enable_if<
  52. !(std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value)
  53. >::type
  54. >
  55. R operator()( U&& u, A... a ) const
  56. {
  57. return (get_pointer( std::forward<U>( u ) )->*pm_)( std::forward<A>( a )... );
  58. }
  59. bool operator==( mf const & rhs ) const
  60. {
  61. return pm_ == rhs.pm_;
  62. }
  63. bool operator!=( mf const & rhs ) const
  64. {
  65. return pm_ != rhs.pm_;
  66. }
  67. };
  68. } // namespace _mfi
  69. //
  70. template<class R, class T, class... A>
  71. auto mem_fn( R (T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
  72. {
  73. return pmf;
  74. }
  75. template<class R, class T, class... A>
  76. auto mem_fn( R (T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
  77. {
  78. return pmf;
  79. }
  80. #if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
  81. template<class R, class T, class... A>
  82. auto mem_fn( R (T::*pmf) (A...) noexcept ) -> _mfi::mf<decltype(pmf), R, T, A...>
  83. {
  84. return pmf;
  85. }
  86. template<class R, class T, class... A>
  87. auto mem_fn( R (T::*pmf) (A...) const noexcept ) -> _mfi::mf<decltype(pmf), R, T, A...>
  88. {
  89. return pmf;
  90. }
  91. #endif // #if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
  92. #if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64)
  93. template<class R, class T, class... A>
  94. auto mem_fn( R (__cdecl T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
  95. {
  96. return pmf;
  97. }
  98. template<class R, class T, class... A>
  99. auto mem_fn( R (__cdecl T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
  100. {
  101. return pmf;
  102. }
  103. #endif // #if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64)
  104. #if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64)
  105. template<class R, class T, class... A>
  106. auto mem_fn( R (__stdcall T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
  107. {
  108. return pmf;
  109. }
  110. template<class R, class T, class... A>
  111. auto mem_fn( R (__stdcall T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
  112. {
  113. return pmf;
  114. }
  115. #endif // #if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64)
  116. #if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64)
  117. template<class R, class T, class... A>
  118. auto mem_fn( R (__fastcall T::*pmf) (A...) ) -> _mfi::mf<decltype(pmf), R, T, A...>
  119. {
  120. return pmf;
  121. }
  122. template<class R, class T, class... A>
  123. auto mem_fn( R (__fastcall T::*pmf) (A...) const ) -> _mfi::mf<decltype(pmf), R, T, A...>
  124. {
  125. return pmf;
  126. }
  127. #endif // #if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64)
  128. // data member support
  129. namespace _mfi
  130. {
  131. template<class R, class T> class dm
  132. {
  133. public:
  134. typedef R const & result_type;
  135. typedef T const * argument_type;
  136. private:
  137. typedef R (T::*Pm);
  138. Pm pm_;
  139. public:
  140. dm( Pm pm ): pm_( pm ) {}
  141. template<class U,
  142. class Ud = typename _mfi::remove_cvref<U>::type,
  143. class En = typename std::enable_if<
  144. std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value
  145. >::type
  146. >
  147. auto operator()( U&& u ) const -> decltype( std::forward<U>( u ).*pm_ )
  148. {
  149. return std::forward<U>( u ).*pm_;
  150. }
  151. template<class U,
  152. class Ud = typename _mfi::remove_cvref<U>::type,
  153. class E1 = void,
  154. class En = typename std::enable_if<
  155. !(std::is_same<T, Ud>::value || std::is_base_of<T, Ud>::value)
  156. >::type
  157. >
  158. auto operator()( U&& u ) const -> decltype( get_pointer( std::forward<U>( u ) )->*pm_ )
  159. {
  160. return get_pointer( std::forward<U>( u ) )->*pm_;
  161. }
  162. #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
  163. template<class U>
  164. R& operator()( U* u ) const
  165. {
  166. return u->*pm_;
  167. }
  168. template<class U>
  169. R const& operator()( U const* u ) const
  170. {
  171. return u->*pm_;
  172. }
  173. #endif
  174. bool operator==( dm const & rhs ) const
  175. {
  176. return pm_ == rhs.pm_;
  177. }
  178. bool operator!=( dm const & rhs ) const
  179. {
  180. return pm_ != rhs.pm_;
  181. }
  182. };
  183. } // namespace _mfi
  184. template<class R, class T,
  185. class E = typename std::enable_if< !std::is_function<R>::value >::type
  186. >
  187. _mfi::dm<R, T> mem_fn( R T::*pm )
  188. {
  189. return pm;
  190. }
  191. } // namespace boost
  192. #endif // #ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED