317 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			317 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | //
 | ||
|  | // execution/sender.hpp
 | ||
|  | // ~~~~~~~~~~~~~~~~~~~~
 | ||
|  | //
 | ||
|  | // Copyright (c) 2003-2023 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 ASIO_EXECUTION_SENDER_HPP
 | ||
|  | #define ASIO_EXECUTION_SENDER_HPP
 | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | # pragma once
 | ||
|  | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | 
 | ||
|  | #include "asio/detail/config.hpp"
 | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_DEPRECATED)
 | ||
|  | 
 | ||
|  | #include "asio/detail/type_traits.hpp"
 | ||
|  | #include "asio/execution/detail/as_invocable.hpp"
 | ||
|  | #include "asio/execution/detail/void_receiver.hpp"
 | ||
|  | #include "asio/execution/executor.hpp"
 | ||
|  | #include "asio/execution/receiver.hpp"
 | ||
|  | 
 | ||
|  | #include "asio/detail/push_options.hpp"
 | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_ALIAS_TEMPLATES) \
 | ||
|  |   && defined(ASIO_HAS_VARIADIC_TEMPLATES) \ | ||
|  |   && defined(ASIO_HAS_DECLTYPE) \ | ||
|  |   && !defined(ASIO_MSVC) || (_MSC_VER >= 1910) | ||
|  | # define ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT 1
 | ||
|  | #endif // defined(ASIO_HAS_ALIAS_TEMPLATES)
 | ||
|  |        //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  |        //   && defined(ASIO_HAS_DECLTYPE)
 | ||
|  |        //   && !defined(ASIO_MSVC) || (_MSC_VER >= 1910)
 | ||
|  | 
 | ||
|  | namespace asio { | ||
|  | namespace execution { | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | namespace sender_base_ns { struct sender_base {}; } | ||
|  | 
 | ||
|  | template <typename S, typename = void> | ||
|  | struct sender_traits_base | ||
|  | { | ||
|  |   typedef void asio_execution_sender_traits_base_is_unspecialised; | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename S> | ||
|  | struct sender_traits_base<S, | ||
|  |     typename enable_if< | ||
|  |       is_base_of<sender_base_ns::sender_base, S>::value | ||
|  |     >::type> | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename S, typename = void, typename = void, typename = void> | ||
|  | struct has_sender_types : false_type | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
 | ||
|  | 
 | ||
|  | template < | ||
|  |     template < | ||
|  |       template <typename...> class Tuple, | ||
|  |       template <typename...> class Variant | ||
|  |     > class> | ||
|  | struct has_value_types | ||
|  | { | ||
|  |   typedef void type; | ||
|  | }; | ||
|  | 
 | ||
|  | template < | ||
|  |   template < | ||
|  |     template <typename...> class Variant | ||
|  |   > class> | ||
|  | struct has_error_types | ||
|  | { | ||
|  |   typedef void type; | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename S> | ||
|  | struct has_sender_types<S, | ||
|  |     typename has_value_types<S::template value_types>::type, | ||
|  |     typename has_error_types<S::template error_types>::type, | ||
|  |     typename conditional<S::sends_done, void, void>::type> : true_type | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename S> | ||
|  | struct sender_traits_base<S, | ||
|  |     typename enable_if< | ||
|  |       has_sender_types<S>::value | ||
|  |     >::type> | ||
|  | { | ||
|  |   template < | ||
|  |       template <typename...> class Tuple, | ||
|  |       template <typename...> class Variant> | ||
|  |   using value_types = typename S::template value_types<Tuple, Variant>; | ||
|  | 
 | ||
|  |   template <template <typename...> class Variant> | ||
|  |   using error_types = typename S::template error_types<Variant>; | ||
|  | 
 | ||
|  |   ASIO_STATIC_CONSTEXPR(bool, sends_done = S::sends_done); | ||
|  | }; | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
 | ||
|  | 
 | ||
|  | template <typename S> | ||
|  | struct sender_traits_base<S, | ||
|  |     typename enable_if< | ||
|  |       !has_sender_types<S>::value | ||
|  |         && detail::is_executor_of_impl<S, | ||
|  |           as_invocable<void_receiver, S> >::value | ||
|  |     >::type> | ||
|  | { | ||
|  | #if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT) \
 | ||
|  |   && defined(ASIO_HAS_STD_EXCEPTION_PTR) | ||
|  | 
 | ||
|  |   template < | ||
|  |       template <typename...> class Tuple, | ||
|  |       template <typename...> class Variant> | ||
|  |   using value_types = Variant<Tuple<>>; | ||
|  | 
 | ||
|  |   template <template <typename...> class Variant> | ||
|  |   using error_types = Variant<std::exception_ptr>; | ||
|  | 
 | ||
|  |   ASIO_STATIC_CONSTEXPR(bool, sends_done = true); | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
 | ||
|  |        //   && defined(ASIO_HAS_STD_EXCEPTION_PTR)
 | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | 
 | ||
|  | /// Base class used for tagging senders.
 | ||
|  | #if defined(GENERATING_DOCUMENTATION)
 | ||
|  | typedef unspecified sender_base; | ||
|  | #else // defined(GENERATING_DOCUMENTATION)
 | ||
|  | typedef detail::sender_base_ns::sender_base sender_base; | ||
|  | #endif // defined(GENERATING_DOCUMENTATION)
 | ||
|  | 
 | ||
|  | /// Traits for senders.
 | ||
|  | template <typename S> | ||
|  | struct sender_traits | ||
|  | #if !defined(GENERATING_DOCUMENTATION)
 | ||
|  |   : detail::sender_traits_base<S> | ||
|  | #endif // !defined(GENERATING_DOCUMENTATION)
 | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | template <typename S, typename = void> | ||
|  | struct has_sender_traits : true_type | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename S> | ||
|  | struct has_sender_traits<S, | ||
|  |     typename enable_if< | ||
|  |       is_same< | ||
|  |         typename asio::execution::sender_traits< | ||
|  |           S>::asio_execution_sender_traits_base_is_unspecialised, | ||
|  |         void | ||
|  |       >::value | ||
|  |     >::type> : false_type | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | 
 | ||
|  | /// The is_sender trait detects whether a type T satisfies the
 | ||
|  | /// execution::sender concept.
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Class template @c is_sender is a type trait that is derived from @c | ||
|  |  * true_type if the type @c T meets the concept definition for a sender, | ||
|  |  * otherwise @c false_type. | ||
|  |  */ | ||
|  | template <typename T> | ||
|  | struct is_sender : | ||
|  | #if defined(GENERATING_DOCUMENTATION)
 | ||
|  |   integral_constant<bool, automatically_determined> | ||
|  | #else // defined(GENERATING_DOCUMENTATION)
 | ||
|  |   conditional< | ||
|  |     detail::has_sender_traits<typename remove_cvref<T>::type>::value, | ||
|  |     is_move_constructible<typename remove_cvref<T>::type>, | ||
|  |     false_type | ||
|  |   >::type | ||
|  | #endif // defined(GENERATING_DOCUMENTATION)
 | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | ASIO_CONSTEXPR const bool is_sender_v = is_sender<T>::value; | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
 | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | ASIO_CONCEPT sender = is_sender<T>::value; | ||
|  | 
 | ||
|  | #define ASIO_EXECUTION_SENDER ::asio::execution::sender
 | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | #define ASIO_EXECUTION_SENDER typename
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | template <typename S, typename R> | ||
|  | struct can_connect; | ||
|  | 
 | ||
|  | /// The is_sender_to trait detects whether a type T satisfies the
 | ||
|  | /// execution::sender_to concept for some receiver.
 | ||
|  | /**
 | ||
|  |  * Class template @c is_sender_to is a type trait that is derived from @c | ||
|  |  * true_type if the type @c T meets the concept definition for a sender | ||
|  |  * for some receiver type R, otherwise @c false. | ||
|  |  */ | ||
|  | template <typename T, typename R> | ||
|  | struct is_sender_to : | ||
|  | #if defined(GENERATING_DOCUMENTATION)
 | ||
|  |   integral_constant<bool, automatically_determined> | ||
|  | #else // defined(GENERATING_DOCUMENTATION)
 | ||
|  |   integral_constant<bool, | ||
|  |     is_sender<T>::value | ||
|  |       && is_receiver<R>::value | ||
|  |       && can_connect<T, R>::value | ||
|  |   > | ||
|  | #endif // defined(GENERATING_DOCUMENTATION)
 | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename T, typename R> | ||
|  | ASIO_CONSTEXPR const bool is_sender_to_v = | ||
|  |   is_sender_to<T, R>::value; | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
 | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | template <typename T, typename R> | ||
|  | ASIO_CONCEPT sender_to = is_sender_to<T, R>::value; | ||
|  | 
 | ||
|  | #define ASIO_EXECUTION_SENDER_TO(r) \
 | ||
|  |   ::asio::execution::sender_to<r> | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | #define ASIO_EXECUTION_SENDER_TO(r) typename
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | /// The is_typed_sender trait detects whether a type T satisfies the
 | ||
|  | /// execution::typed_sender concept.
 | ||
|  | /**
 | ||
|  |  * Class template @c is_typed_sender is a type trait that is derived from @c | ||
|  |  * true_type if the type @c T meets the concept definition for a typed sender, | ||
|  |  * otherwise @c false. | ||
|  |  */ | ||
|  | template <typename T> | ||
|  | struct is_typed_sender : | ||
|  | #if defined(GENERATING_DOCUMENTATION)
 | ||
|  |   integral_constant<bool, automatically_determined> | ||
|  | #else // defined(GENERATING_DOCUMENTATION)
 | ||
|  |   integral_constant<bool, | ||
|  |     is_sender<T>::value | ||
|  |       && detail::has_sender_types< | ||
|  |         sender_traits<typename remove_cvref<T>::type> >::value | ||
|  |   > | ||
|  | #endif // defined(GENERATING_DOCUMENTATION)
 | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_VARIABLE_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | ASIO_CONSTEXPR const bool is_typed_sender_v = is_typed_sender<T>::value; | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
 | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | ASIO_CONCEPT typed_sender = is_typed_sender<T>::value; | ||
|  | 
 | ||
|  | #define ASIO_EXECUTION_TYPED_SENDER \
 | ||
|  |   ::asio::execution::typed_sender | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | #define ASIO_EXECUTION_TYPED_SENDER typename
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_CONCEPTS)
 | ||
|  | 
 | ||
|  | } // namespace execution
 | ||
|  | } // namespace asio
 | ||
|  | 
 | ||
|  | #include "asio/detail/pop_options.hpp"
 | ||
|  | 
 | ||
|  | #include "asio/execution/connect.hpp"
 | ||
|  | 
 | ||
|  | #endif // !defined(ASIO_NO_DEPRECATED)
 | ||
|  | 
 | ||
|  | #endif // ASIO_EXECUTION_SENDER_HPP
 |