// // execution/execute.hpp // ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_ASIO_EXECUTION_EXECUTE_HPP #define BOOST_ASIO_EXECUTION_EXECUTE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include #include #include #include #include #if defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { /// A customisation point that executes a function on an executor. /** * The name execution::execute denotes a customisation point object. * * For some subexpressions e and f, let E be a type * such that decltype((e)) is E and let F be a type * such that decltype((f)) is F. The expression * execution::execute(e, f) is ill-formed if F does not model * invocable, or if E does not model either executor * or sender. Otherwise, it is expression-equivalent to: * * @li e.execute(f), if that expression is valid. If the function * selected does not execute the function object f on the executor * e, the program is ill-formed with no diagnostic required. * * @li Otherwise, execute(e, f), if that expression is valid, with * overload resolution performed in a context that includes the declaration * void execute(); and that does not include a declaration of * execution::execute. If the function selected by overload * resolution does not execute the function object f on the executor * e, the program is ill-formed with no diagnostic required. */ inline constexpr unspecified execute = unspecified; /// A type trait that determines whether a @c execute expression is well-formed. /** * Class template @c can_execute is a trait that is derived from * @c true_type if the expression execution::execute(std::declval(), * std::declval()) is well formed; otherwise @c false_type. */ template struct can_execute : integral_constant { }; } // namespace execution } // namespace asio } // namespace boost #else // defined(GENERATING_DOCUMENTATION) namespace boost { namespace asio { namespace execution { template struct is_sender_to; namespace detail { template void submit_helper(BOOST_ASIO_MOVE_ARG(S) s, BOOST_ASIO_MOVE_ARG(R) r); } // namespace detail } // namespace execution } // namespace asio } // namespace boost namespace asio_execution_execute_fn { using boost::asio::conditional; using boost::asio::decay; using boost::asio::declval; using boost::asio::enable_if; using boost::asio::execution::detail::as_receiver; using boost::asio::execution::detail::is_as_invocable; using boost::asio::execution::is_sender_to; using boost::asio::false_type; using boost::asio::result_of; using boost::asio::traits::execute_free; using boost::asio::traits::execute_member; using boost::asio::true_type; using boost::asio::void_type; void execute(); enum overload_type { call_member, call_free, adapter, ill_formed }; template struct call_traits { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed); }; template struct call_traits::type, F>::is_valid >::type> : execute_member::type, F> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template struct call_traits, F>::is_valid >::type, typename enable_if< execute_free::is_valid >::type> : execute_free { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; template struct call_traits::type, F>::is_valid >::type, typename enable_if< !execute_free::is_valid >::type, typename void_type< typename result_of::type&()>::type >::type, typename enable_if< !is_as_invocable::type>::value >::type, typename enable_if< is_sender_to::type, T> >::value >::type> { BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true); BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; struct impl { template struct proxy { #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) struct type { template auto execute(BOOST_ASIO_MOVE_ARG(F) f) noexcept( noexcept( declval::type>().execute( BOOST_ASIO_MOVE_CAST(F)(f)) ) ) -> decltype( declval::type>().execute( BOOST_ASIO_MOVE_CAST(F)(f)) ); }; #else // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) typedef T type; #endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) }; template BOOST_ASIO_CONSTEXPR typename enable_if< call_traits::overload == call_member, typename call_traits::result_type >::type operator()( BOOST_ASIO_MOVE_ARG(T) t, BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT_IF(( call_traits::is_noexcept)) { return BOOST_ASIO_MOVE_CAST(T)(t).execute(BOOST_ASIO_MOVE_CAST(F)(f)); } template BOOST_ASIO_CONSTEXPR typename enable_if< call_traits::overload == call_free, typename call_traits::result_type >::type operator()( BOOST_ASIO_MOVE_ARG(T) t, BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT_IF(( call_traits::is_noexcept)) { return execute(BOOST_ASIO_MOVE_CAST(T)(t), BOOST_ASIO_MOVE_CAST(F)(f)); } template BOOST_ASIO_CONSTEXPR typename enable_if< call_traits::overload == adapter, typename call_traits::result_type >::type operator()( BOOST_ASIO_MOVE_ARG(T) t, BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT_IF(( call_traits::is_noexcept)) { return boost::asio::execution::detail::submit_helper( BOOST_ASIO_MOVE_CAST(T)(t), as_receiver::type, T>( BOOST_ASIO_MOVE_CAST(F)(f), 0)); } }; template struct static_instance { static const T instance; }; template const T static_instance::instance = {}; } // namespace asio_execution_execute_fn namespace boost { namespace asio { namespace execution { namespace { static BOOST_ASIO_CONSTEXPR const asio_execution_execute_fn::impl& execute = asio_execution_execute_fn::static_instance<>::instance; } // namespace typedef asio_execution_execute_fn::impl execute_t; template struct can_execute : integral_constant::overload != asio_execution_execute_fn::ill_formed> { }; #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) template constexpr bool can_execute_v = can_execute::value; #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES) } // namespace execution } // namespace asio } // namespace boost #endif // defined(GENERATING_DOCUMENTATION) #include #endif // BOOST_ASIO_EXECUTION_EXECUTE_HPP