123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- //
- // 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 <boost/asio/detail/config.hpp>
- #include <boost/asio/detail/type_traits.hpp>
- #include <boost/asio/execution/detail/as_invocable.hpp>
- #include <boost/asio/execution/detail/as_receiver.hpp>
- #include <boost/asio/traits/execute_member.hpp>
- #include <boost/asio/traits/execute_free.hpp>
- #include <boost/asio/detail/push_options.hpp>
- #if defined(GENERATING_DOCUMENTATION)
- namespace boost {
- namespace asio {
- namespace execution {
- /// A customisation point that executes a function on an executor.
- /**
- * The name <tt>execution::execute</tt> denotes a customisation point object.
- *
- * For some subexpressions <tt>e</tt> and <tt>f</tt>, let <tt>E</tt> be a type
- * such that <tt>decltype((e))</tt> is <tt>E</tt> and let <tt>F</tt> be a type
- * such that <tt>decltype((f))</tt> is <tt>F</tt>. The expression
- * <tt>execution::execute(e, f)</tt> is ill-formed if <tt>F</tt> does not model
- * <tt>invocable</tt>, or if <tt>E</tt> does not model either <tt>executor</tt>
- * or <tt>sender</tt>. Otherwise, it is expression-equivalent to:
- *
- * @li <tt>e.execute(f)</tt>, if that expression is valid. If the function
- * selected does not execute the function object <tt>f</tt> on the executor
- * <tt>e</tt>, the program is ill-formed with no diagnostic required.
- *
- * @li Otherwise, <tt>execute(e, f)</tt>, if that expression is valid, with
- * overload resolution performed in a context that includes the declaration
- * <tt>void execute();</tt> and that does not include a declaration of
- * <tt>execution::execute</tt>. If the function selected by overload
- * resolution does not execute the function object <tt>f</tt> on the executor
- * <tt>e</tt>, 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 <tt>execution::execute(std::declval<T>(),
- * std::declval<F>())</tt> is well formed; otherwise @c false_type.
- */
- template <typename T, typename F>
- struct can_execute :
- integral_constant<bool, automatically_determined>
- {
- };
- } // namespace execution
- } // namespace asio
- } // namespace boost
- #else // defined(GENERATING_DOCUMENTATION)
- namespace boost {
- namespace asio {
- namespace execution {
- template <typename T, typename R>
- struct is_sender_to;
- namespace detail {
- template <typename S, typename R>
- 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 <typename Impl, typename T, typename F, typename = void,
- typename = void, typename = void, typename = void, typename = void>
- struct call_traits
- {
- BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
- };
- template <typename Impl, typename T, typename F>
- struct call_traits<Impl, T, void(F),
- typename enable_if<
- execute_member<typename Impl::template proxy<T>::type, F>::is_valid
- >::type> :
- execute_member<typename Impl::template proxy<T>::type, F>
- {
- BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
- };
- template <typename Impl, typename T, typename F>
- struct call_traits<Impl, T, void(F),
- typename enable_if<
- !execute_member<typename Impl::template proxy<T>, F>::is_valid
- >::type,
- typename enable_if<
- execute_free<T, F>::is_valid
- >::type> :
- execute_free<T, F>
- {
- BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
- };
- template <typename Impl, typename T, typename F>
- struct call_traits<Impl, T, void(F),
- typename enable_if<
- !execute_member<typename Impl::template proxy<T>::type, F>::is_valid
- >::type,
- typename enable_if<
- !execute_free<T, F>::is_valid
- >::type,
- typename void_type<
- typename result_of<typename decay<F>::type&()>::type
- >::type,
- typename enable_if<
- !is_as_invocable<typename decay<F>::type>::value
- >::type,
- typename enable_if<
- is_sender_to<T, as_receiver<typename decay<F>::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 <typename T>
- struct proxy
- {
- #if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
- struct type
- {
- template <typename F>
- auto execute(BOOST_ASIO_MOVE_ARG(F) f)
- noexcept(
- noexcept(
- declval<typename conditional<true, T, F>::type>().execute(
- BOOST_ASIO_MOVE_CAST(F)(f))
- )
- )
- -> decltype(
- declval<typename conditional<true, T, F>::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 <typename T, typename F>
- BOOST_ASIO_CONSTEXPR typename enable_if<
- call_traits<impl, T, void(F)>::overload == call_member,
- typename call_traits<impl, T, void(F)>::result_type
- >::type
- operator()(
- BOOST_ASIO_MOVE_ARG(T) t,
- BOOST_ASIO_MOVE_ARG(F) f) const
- BOOST_ASIO_NOEXCEPT_IF((
- call_traits<impl, T, void(F)>::is_noexcept))
- {
- return BOOST_ASIO_MOVE_CAST(T)(t).execute(BOOST_ASIO_MOVE_CAST(F)(f));
- }
- template <typename T, typename F>
- BOOST_ASIO_CONSTEXPR typename enable_if<
- call_traits<impl, T, void(F)>::overload == call_free,
- typename call_traits<impl, T, void(F)>::result_type
- >::type
- operator()(
- BOOST_ASIO_MOVE_ARG(T) t,
- BOOST_ASIO_MOVE_ARG(F) f) const
- BOOST_ASIO_NOEXCEPT_IF((
- call_traits<impl, T, void(F)>::is_noexcept))
- {
- return execute(BOOST_ASIO_MOVE_CAST(T)(t), BOOST_ASIO_MOVE_CAST(F)(f));
- }
- template <typename T, typename F>
- BOOST_ASIO_CONSTEXPR typename enable_if<
- call_traits<impl, T, void(F)>::overload == adapter,
- typename call_traits<impl, T, void(F)>::result_type
- >::type
- operator()(
- BOOST_ASIO_MOVE_ARG(T) t,
- BOOST_ASIO_MOVE_ARG(F) f) const
- BOOST_ASIO_NOEXCEPT_IF((
- call_traits<impl, T, void(F)>::is_noexcept))
- {
- return boost::asio::execution::detail::submit_helper(
- BOOST_ASIO_MOVE_CAST(T)(t),
- as_receiver<typename decay<F>::type, T>(
- BOOST_ASIO_MOVE_CAST(F)(f), 0));
- }
- };
- template <typename T = impl>
- struct static_instance
- {
- static const T instance;
- };
- template <typename T>
- const T static_instance<T>::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 <typename T, typename F>
- struct can_execute :
- integral_constant<bool,
- asio_execution_execute_fn::call_traits<
- execute_t, T, void(F)>::overload !=
- asio_execution_execute_fn::ill_formed>
- {
- };
- #if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
- template <typename T, typename F>
- constexpr bool can_execute_v = can_execute<T, F>::value;
- #endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
- } // namespace execution
- } // namespace asio
- } // namespace boost
- #endif // defined(GENERATING_DOCUMENTATION)
- #include <boost/asio/detail/pop_options.hpp>
- #endif // BOOST_ASIO_EXECUTION_EXECUTE_HPP
|