#ifndef BOOST_COMPAT_MEM_FN_HPP_INCLUDED #define BOOST_COMPAT_MEM_FN_HPP_INCLUDED // Copyright 2024 Peter Dimov // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #include #include #include namespace boost { namespace compat { namespace detail { template, class Ud = remove_cvref_t> struct is_same_or_base: std::integral_constant::value || std::is_base_of::value> { }; template struct is_reference_wrapper_: std::false_type {}; template struct is_reference_wrapper_< std::reference_wrapper >: std::true_type {}; template struct is_reference_wrapper: is_reference_wrapper_< remove_cvref_t > {}; template struct _mfn { M T::* pm_; template::value>> constexpr auto operator()( U&& u, A&&... a ) const BOOST_COMPAT_RETURNS( (std::forward(u).*pm_)( std::forward(a)... ) ) template::value && is_reference_wrapper::value>> constexpr auto operator()( U&& u, A&&... a ) const BOOST_COMPAT_RETURNS( (u.get().*pm_)( std::forward(a)... ) ) template::value && !is_reference_wrapper::value>> constexpr auto operator()( U&& u, A&&... a ) const BOOST_COMPAT_RETURNS( ((*std::forward(u)).*pm_)( std::forward(a)... ) ) }; template struct _md { M T::* pm_; template::value>> constexpr auto operator()( U&& u ) const BOOST_COMPAT_RETURNS( std::forward(u).*pm_ ) template::value && is_reference_wrapper::value>> constexpr auto operator()( U&& u ) const BOOST_COMPAT_RETURNS( u.get().*pm_ ) template::value && !is_reference_wrapper::value>> constexpr auto operator()( U&& u ) const BOOST_COMPAT_RETURNS( (*std::forward(u)).*pm_ ) }; } // namespace detail template::value > > constexpr auto mem_fn( M T::* pm ) noexcept -> detail::_mfn { return detail::_mfn{ pm }; } template::value > > constexpr auto mem_fn( M T::* pm ) noexcept -> detail::_md { return detail::_md{ pm }; } } // namespace compat } // namespace boost #endif // BOOST_COMPAT_MEM_FN_HPP_INCLUDED