File indexing completed on 2025-04-26 08:26:32
0001 #ifndef BOOST_COMPAT_MEM_FN_HPP_INCLUDED
0002 #define BOOST_COMPAT_MEM_FN_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <boost/compat/type_traits.hpp>
0009 #include <boost/compat/detail/returns.hpp>
0010 #include <functional>
0011
0012 namespace boost {
0013 namespace compat {
0014
0015 namespace detail {
0016
0017 template<class T, class U, class Td = remove_cvref_t<T>, class Ud = remove_cvref_t<U>>
0018 struct is_same_or_base: std::integral_constant<bool, std::is_same<Td, Ud>::value || std::is_base_of<Td, Ud>::value>
0019 {
0020 };
0021
0022 template<class T> struct is_reference_wrapper_: std::false_type {};
0023 template<class T> struct is_reference_wrapper_< std::reference_wrapper<T> >: std::true_type {};
0024
0025 template<class T> struct is_reference_wrapper: is_reference_wrapper_< remove_cvref_t<T> > {};
0026
0027 template<class M, class T> struct _mfn
0028 {
0029 M T::* pm_;
0030
0031 template<class U, class... A, class En = enable_if_t<is_same_or_base<T, U>::value>>
0032 constexpr auto operator()( U&& u, A&&... a ) const
0033 BOOST_COMPAT_RETURNS( (std::forward<U>(u).*pm_)( std::forward<A>(a)... ) )
0034
0035 template<class U, class... A, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && is_reference_wrapper<U>::value>>
0036 constexpr auto operator()( U&& u, A&&... a ) const
0037 BOOST_COMPAT_RETURNS( (u.get().*pm_)( std::forward<A>(a)... ) )
0038
0039 template<class U, class... A, class = void, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && !is_reference_wrapper<U>::value>>
0040 constexpr auto operator()( U&& u, A&&... a ) const
0041 BOOST_COMPAT_RETURNS( ((*std::forward<U>(u)).*pm_)( std::forward<A>(a)... ) )
0042 };
0043
0044 template<class M, class T> struct _md
0045 {
0046 M T::* pm_;
0047
0048 template<class U, class En = enable_if_t<is_same_or_base<T, U>::value>>
0049 constexpr auto operator()( U&& u ) const
0050 BOOST_COMPAT_RETURNS( std::forward<U>(u).*pm_ )
0051
0052 template<class U, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && is_reference_wrapper<U>::value>>
0053 constexpr auto operator()( U&& u ) const
0054 BOOST_COMPAT_RETURNS( u.get().*pm_ )
0055
0056 template<class U, class = void, class = void, class En = enable_if_t< !is_same_or_base<T, U>::value && !is_reference_wrapper<U>::value>>
0057 constexpr auto operator()( U&& u ) const
0058 BOOST_COMPAT_RETURNS( (*std::forward<U>(u)).*pm_ )
0059 };
0060
0061 }
0062
0063 template<class M, class T, class En = enable_if_t< std::is_function<M>::value > >
0064 constexpr auto mem_fn( M T::* pm ) noexcept -> detail::_mfn<M, T>
0065 {
0066 return detail::_mfn<M, T>{ pm };
0067 }
0068
0069 template<class M, class T, class = void, class En = enable_if_t< !std::is_function<M>::value > >
0070 constexpr auto mem_fn( M T::* pm ) noexcept -> detail::_md<M, T>
0071 {
0072 return detail::_md<M, T>{ pm };
0073 }
0074
0075 }
0076 }
0077
0078 #endif