Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-26 08:26:32

0001 #ifndef BOOST_COMPAT_INVOKE_HPP_INCLUDED
0002 #define BOOST_COMPAT_INVOKE_HPP_INCLUDED
0003 
0004 // Copyright 2024 Peter Dimov
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 
0008 #include <boost/compat/mem_fn.hpp>
0009 #include <boost/compat/type_traits.hpp>
0010 #include <boost/compat/detail/returns.hpp>
0011 #include <boost/config.hpp>
0012 #include <boost/config/workaround.hpp>
0013 #include <utility>
0014 
0015 namespace boost {
0016 namespace compat {
0017 
0018 // invoke
0019 
0020 template<class F, class... A>
0021 constexpr auto invoke( F&& f, A&&... a )
0022 BOOST_COMPAT_RETURNS( std::forward<F>(f)(std::forward<A>(a)...) )
0023 
0024 template<class M, class T, class... A>
0025 constexpr auto invoke( M T::* pm, A&&... a )
0026 BOOST_COMPAT_RETURNS( compat::mem_fn(pm)(std::forward<A>(a)...) )
0027 
0028 // invoke_result_t
0029 
0030 template<class F, class... A> using invoke_result_t = decltype( compat::invoke( std::declval<F>(), std::declval<A>()... ) );
0031 
0032 // is_invocable
0033 
0034 namespace detail {
0035 
0036 template<class, class F, class... A> struct is_invocable_: std::false_type {};
0037 template<class F, class... A> struct is_invocable_< void_t<invoke_result_t<F, A...>>, F, A... >: std::true_type {};
0038 
0039 } // namespace detail
0040 
0041 template<class F, class... A> struct is_invocable: detail::is_invocable_<void, F, A...> {};
0042 
0043 // is_nothrow_invocable
0044 
0045 #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0046 
0047 template<class F, class... A> struct is_nothrow_invocable: std::false_type {};
0048 
0049 #else
0050 
0051 namespace detail {
0052 
0053 template<class F, class... A> struct is_nothrow_invocable_
0054 {
0055     using type = std::integral_constant<bool, noexcept( compat::invoke( std::declval<F>(), std::declval<A>()... ) )>;
0056 };
0057 
0058 } // namespace detail
0059 
0060 template<class F, class... A> struct is_nothrow_invocable: conditional_t< is_invocable<F, A...>::value, detail::is_nothrow_invocable_<F, A...>, std::false_type >::type {};
0061 
0062 #endif
0063 
0064 // invoke_r
0065 
0066 template<class R, class F, class... A, class En = enable_if_t<
0067     std::is_void<R>::value && is_invocable<F, A...>::value >>
0068 constexpr R invoke_r( F&& f, A&&... a )
0069     noexcept( noexcept( static_cast<R>( compat::invoke( std::forward<F>(f), std::forward<A>(a)... ) ) ) )
0070 {
0071     return static_cast<R>( compat::invoke( std::forward<F>(f), std::forward<A>(a)... ) );
0072 }
0073 
0074 template<class R, class F, class... A, class = void, class En = enable_if_t<
0075     !std::is_void<R>::value && std::is_convertible< invoke_result_t<F, A...>, R >::value >>
0076 constexpr R invoke_r( F&& f, A&&... a )
0077     noexcept( noexcept( static_cast<R>( compat::invoke( std::forward<F>(f), std::forward<A>(a)... ) ) ) )
0078 {
0079     return compat::invoke( std::forward<F>(f), std::forward<A>(a)... );
0080 }
0081 
0082 // is_invocable_r
0083 
0084 namespace detail {
0085 
0086 template<class R, class F, class... A> struct is_invocable_r_: std::is_convertible< invoke_result_t<F, A...>, R > {};
0087 
0088 } // namespace detail
0089 
0090 template<class R, class F, class... A> struct is_invocable_r:
0091     conditional_t< !is_invocable<F, A...>::value, std::false_type,
0092     conditional_t< std::is_void<R>::value, std::true_type,
0093     detail::is_invocable_r_<R, F, A...> >> {};
0094 
0095 // is_nothrow_invocable_r
0096 
0097 #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0098 
0099 template<class R, class F, class... A> struct is_nothrow_invocable_r: std::false_type {};
0100 
0101 #else
0102 
0103 namespace detail {
0104 
0105 template<class R, class F, class... A> struct is_nothrow_invocable_r_
0106 {
0107     using type = std::integral_constant<bool, noexcept( compat::invoke_r<R>( std::declval<F>(), std::declval<A>()... ) )>;
0108 };
0109 
0110 } // namespace detail
0111 
0112 template<class R, class F, class... A> struct is_nothrow_invocable_r: conditional_t< is_invocable_r<R, F, A...>::value, detail::is_nothrow_invocable_r_<R, F, A...>, std::false_type >::type {};
0113 
0114 #endif
0115 
0116 } // namespace compat
0117 } // namespace boost
0118 
0119 #endif // BOOST_COMPAT_INVOKE_HPP_INCLUDED