2664 lines
		
	
	
		
			78 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			2664 lines
		
	
	
		
			78 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | //
 | ||
|  | // execution/any_executor.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_ANY_EXECUTOR_HPP
 | ||
|  | #define ASIO_EXECUTION_ANY_EXECUTOR_HPP
 | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | # pragma once
 | ||
|  | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | 
 | ||
|  | #include "asio/detail/config.hpp"
 | ||
|  | #include <new>
 | ||
|  | #include <typeinfo>
 | ||
|  | #include "asio/detail/assert.hpp"
 | ||
|  | #include "asio/detail/atomic_count.hpp"
 | ||
|  | #include "asio/detail/cstddef.hpp"
 | ||
|  | #include "asio/detail/executor_function.hpp"
 | ||
|  | #include "asio/detail/memory.hpp"
 | ||
|  | #include "asio/detail/non_const_lvalue.hpp"
 | ||
|  | #include "asio/detail/scoped_ptr.hpp"
 | ||
|  | #include "asio/detail/type_traits.hpp"
 | ||
|  | #include "asio/detail/throw_exception.hpp"
 | ||
|  | #include "asio/detail/variadic_templates.hpp"
 | ||
|  | #include "asio/execution/bad_executor.hpp"
 | ||
|  | #include "asio/execution/blocking.hpp"
 | ||
|  | #include "asio/execution/execute.hpp"
 | ||
|  | #include "asio/execution/executor.hpp"
 | ||
|  | #include "asio/prefer.hpp"
 | ||
|  | #include "asio/query.hpp"
 | ||
|  | #include "asio/require.hpp"
 | ||
|  | 
 | ||
|  | #include "asio/detail/push_options.hpp"
 | ||
|  | 
 | ||
|  | namespace asio { | ||
|  | 
 | ||
|  | #if defined(GENERATING_DOCUMENTATION)
 | ||
|  | 
 | ||
|  | namespace execution { | ||
|  | 
 | ||
|  | /// Polymorphic executor wrapper.
 | ||
|  | template <typename... SupportableProperties> | ||
|  | class any_executor | ||
|  | { | ||
|  | public: | ||
|  |   /// Default constructor.
 | ||
|  |   any_executor() noexcept; | ||
|  | 
 | ||
|  |   /// Construct in an empty state. Equivalent effects to default constructor.
 | ||
|  |   any_executor(nullptr_t) noexcept; | ||
|  | 
 | ||
|  |   /// Copy constructor.
 | ||
|  |   any_executor(const any_executor& e) noexcept; | ||
|  | 
 | ||
|  |   /// Move constructor.
 | ||
|  |   any_executor(any_executor&& e) noexcept; | ||
|  | 
 | ||
|  |   /// Construct to point to the same target as another any_executor.
 | ||
|  |   template <class... OtherSupportableProperties> | ||
|  |     any_executor(any_executor<OtherSupportableProperties...> e); | ||
|  | 
 | ||
|  |   /// Construct to point to the same target as another any_executor.
 | ||
|  |   template <class... OtherSupportableProperties> | ||
|  |     any_executor(std::nothrow_t, | ||
|  |       any_executor<OtherSupportableProperties...> e) noexcept; | ||
|  | 
 | ||
|  |   /// Construct to point to the same target as another any_executor.
 | ||
|  |   any_executor(std::nothrow_t, const any_executor& e) noexcept; | ||
|  | 
 | ||
|  |   /// Construct to point to the same target as another any_executor.
 | ||
|  |   any_executor(std::nothrow_t, any_executor&& e) noexcept; | ||
|  | 
 | ||
|  |   /// Construct a polymorphic wrapper for the specified executor.
 | ||
|  |   template <typename Executor> | ||
|  |   any_executor(Executor e); | ||
|  | 
 | ||
|  |   /// Construct a polymorphic wrapper for the specified executor.
 | ||
|  |   template <typename Executor> | ||
|  |   any_executor(std::nothrow_t, Executor e) noexcept; | ||
|  | 
 | ||
|  |   /// Assignment operator.
 | ||
|  |   any_executor& operator=(const any_executor& e) noexcept; | ||
|  | 
 | ||
|  |   /// Move assignment operator.
 | ||
|  |   any_executor& operator=(any_executor&& e) noexcept; | ||
|  | 
 | ||
|  |   /// Assignment operator that sets the polymorphic wrapper to the empty state.
 | ||
|  |   any_executor& operator=(nullptr_t); | ||
|  | 
 | ||
|  |   /// Assignment operator to create a polymorphic wrapper for the specified
 | ||
|  |   /// executor.
 | ||
|  |   template <typename Executor> | ||
|  |   any_executor& operator=(Executor e); | ||
|  | 
 | ||
|  |   /// Destructor.
 | ||
|  |   ~any_executor(); | ||
|  | 
 | ||
|  |   /// Swap targets with another polymorphic wrapper.
 | ||
|  |   void swap(any_executor& other) noexcept; | ||
|  | 
 | ||
|  |   /// Obtain a polymorphic wrapper with the specified property.
 | ||
|  |   /**
 | ||
|  |    * Do not call this function directly. It is intended for use with the | ||
|  |    * asio::require and asio::prefer customisation points. | ||
|  |    * | ||
|  |    * For example: | ||
|  |    * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...; | ||
|  |    * auto ex2 = asio::requre(ex, execution::blocking.possibly); @endcode | ||
|  |    */ | ||
|  |   template <typename Property> | ||
|  |   any_executor require(Property) const; | ||
|  | 
 | ||
|  |   /// Obtain a polymorphic wrapper with the specified property.
 | ||
|  |   /**
 | ||
|  |    * Do not call this function directly. It is intended for use with the | ||
|  |    * asio::prefer customisation point. | ||
|  |    * | ||
|  |    * For example: | ||
|  |    * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...; | ||
|  |    * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode | ||
|  |    */ | ||
|  |   template <typename Property> | ||
|  |   any_executor prefer(Property) const; | ||
|  | 
 | ||
|  |   /// Obtain the value associated with the specified property.
 | ||
|  |   /**
 | ||
|  |    * Do not call this function directly. It is intended for use with the | ||
|  |    * asio::query customisation point. | ||
|  |    * | ||
|  |    * For example: | ||
|  |    * @code execution::any_executor<execution::occupancy_t> ex = ...; | ||
|  |    * size_t n = asio::query(ex, execution::occupancy); @endcode | ||
|  |    */ | ||
|  |   template <typename Property> | ||
|  |   typename Property::polymorphic_query_result_type query(Property) const; | ||
|  | 
 | ||
|  |   /// Execute the function on the target executor.
 | ||
|  |   /**
 | ||
|  |    * Throws asio::bad_executor if the polymorphic wrapper has no target. | ||
|  |    */ | ||
|  |   template <typename Function> | ||
|  |   void execute(Function&& f) const; | ||
|  | 
 | ||
|  |   /// Obtain the underlying execution context.
 | ||
|  |   /**
 | ||
|  |    * This function is provided for backward compatibility. It is automatically | ||
|  |    * defined when the @c SupportableProperties... list includes a property of | ||
|  |    * type <tt>execution::context_as<U></tt>, for some type <tt>U</tt>. | ||
|  |    */ | ||
|  |   automatically_determined context() const; | ||
|  | 
 | ||
|  |   /// Determine whether the wrapper has a target executor.
 | ||
|  |   /**
 | ||
|  |    * @returns @c true if the polymorphic wrapper has a target executor, | ||
|  |    * otherwise false. | ||
|  |    */ | ||
|  |   explicit operator bool() const noexcept; | ||
|  | 
 | ||
|  |   /// Get the type of the target executor.
 | ||
|  |   const type_info& target_type() const noexcept; | ||
|  | 
 | ||
|  |   /// Get a pointer to the target executor.
 | ||
|  |   template <typename Executor> Executor* target() noexcept; | ||
|  | 
 | ||
|  |   /// Get a pointer to the target executor.
 | ||
|  |   template <typename Executor> const Executor* target() const noexcept; | ||
|  | }; | ||
|  | 
 | ||
|  | /// Equality operator.
 | ||
|  | /**
 | ||
|  |  * @relates any_executor | ||
|  |  */ | ||
|  | template <typename... SupportableProperties> | ||
|  | bool operator==(const any_executor<SupportableProperties...>& a, | ||
|  |     const any_executor<SupportableProperties...>& b) noexcept; | ||
|  | 
 | ||
|  | /// Equality operator.
 | ||
|  | /**
 | ||
|  |  * @relates any_executor | ||
|  |  */ | ||
|  | template <typename... SupportableProperties> | ||
|  | bool operator==(const any_executor<SupportableProperties...>& a, | ||
|  |     nullptr_t) noexcept; | ||
|  | 
 | ||
|  | /// Equality operator.
 | ||
|  | /**
 | ||
|  |  * @relates any_executor | ||
|  |  */ | ||
|  | template <typename... SupportableProperties> | ||
|  | bool operator==(nullptr_t, | ||
|  |     const any_executor<SupportableProperties...>& b) noexcept; | ||
|  | 
 | ||
|  | /// Inequality operator.
 | ||
|  | /**
 | ||
|  |  * @relates any_executor | ||
|  |  */ | ||
|  | template <typename... SupportableProperties> | ||
|  | bool operator!=(const any_executor<SupportableProperties...>& a, | ||
|  |     const any_executor<SupportableProperties...>& b) noexcept; | ||
|  | 
 | ||
|  | /// Inequality operator.
 | ||
|  | /**
 | ||
|  |  * @relates any_executor | ||
|  |  */ | ||
|  | template <typename... SupportableProperties> | ||
|  | bool operator!=(const any_executor<SupportableProperties...>& a, | ||
|  |     nullptr_t) noexcept; | ||
|  | 
 | ||
|  | /// Inequality operator.
 | ||
|  | /**
 | ||
|  |  * @relates any_executor | ||
|  |  */ | ||
|  | template <typename... SupportableProperties> | ||
|  | bool operator!=(nullptr_t, | ||
|  |     const any_executor<SupportableProperties...>& b) noexcept; | ||
|  | 
 | ||
|  | } // namespace execution
 | ||
|  | 
 | ||
|  | #else // defined(GENERATING_DOCUMENTATION)
 | ||
|  | 
 | ||
|  | namespace execution { | ||
|  | 
 | ||
|  | #if !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)
 | ||
|  | #define ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL
 | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename... SupportableProperties> | ||
|  | class any_executor; | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename = void, typename = void, typename = void, | ||
|  |     typename = void, typename = void, typename = void, | ||
|  |     typename = void, typename = void, typename = void> | ||
|  | class any_executor; | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | #endif // !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)
 | ||
|  | 
 | ||
|  | template <typename U> | ||
|  | struct context_as_t; | ||
|  | 
 | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | // Traits used to detect whether a property is requirable or preferable, taking
 | ||
|  | // into account that T::is_requirable or T::is_preferable may not not be well
 | ||
|  | // formed.
 | ||
|  | 
 | ||
|  | template <typename T, typename = void> | ||
|  | struct is_requirable : false_type {}; | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | struct is_requirable<T, typename enable_if<T::is_requirable>::type> : | ||
|  |   true_type {}; | ||
|  | 
 | ||
|  | template <typename T, typename = void> | ||
|  | struct is_preferable : false_type {}; | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | struct is_preferable<T, typename enable_if<T::is_preferable>::type> : | ||
|  |   true_type {}; | ||
|  | 
 | ||
|  | // Trait used to detect context_as property, for backward compatibility.
 | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | struct is_context_as : false_type {}; | ||
|  | 
 | ||
|  | template <typename U> | ||
|  | struct is_context_as<context_as_t<U> > : true_type {}; | ||
|  | 
 | ||
|  | // Helper template to:
 | ||
|  | // - Check if a target can supply the supportable properties.
 | ||
|  | // - Find the first convertible-from-T property in the list.
 | ||
|  | 
 | ||
|  | template <std::size_t I, typename Props> | ||
|  | struct supportable_properties; | ||
|  | 
 | ||
|  | template <std::size_t I, typename Prop> | ||
|  | struct supportable_properties<I, void(Prop)> | ||
|  | { | ||
|  |   template <typename T> | ||
|  |   struct is_valid_target : integral_constant<bool, | ||
|  |       ( | ||
|  |         is_requirable<Prop>::value | ||
|  |           ? can_require<T, Prop>::value | ||
|  |           : true | ||
|  |       ) | ||
|  |       && | ||
|  |       ( | ||
|  |         is_preferable<Prop>::value | ||
|  |           ? can_prefer<T, Prop>::value | ||
|  |           : true | ||
|  |       ) | ||
|  |       && | ||
|  |       ( | ||
|  |         !is_requirable<Prop>::value && !is_preferable<Prop>::value | ||
|  |           ? can_query<T, Prop>::value | ||
|  |           : true | ||
|  |       ) | ||
|  |     > | ||
|  |   { | ||
|  |   }; | ||
|  | 
 | ||
|  |   struct found | ||
|  |   { | ||
|  |     ASIO_STATIC_CONSTEXPR(bool, value = true); | ||
|  |     typedef Prop type; | ||
|  |     typedef typename Prop::polymorphic_query_result_type query_result_type; | ||
|  |     ASIO_STATIC_CONSTEXPR(std::size_t, index = I); | ||
|  |   }; | ||
|  | 
 | ||
|  |   struct not_found | ||
|  |   { | ||
|  |     ASIO_STATIC_CONSTEXPR(bool, value = false); | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_property : | ||
|  |       conditional< | ||
|  |         is_same<T, Prop>::value || is_convertible<T, Prop>::value, | ||
|  |         found, | ||
|  |         not_found | ||
|  |       >::type {}; | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_requirable_property : | ||
|  |       conditional< | ||
|  |         is_requirable<Prop>::value | ||
|  |           && (is_same<T, Prop>::value || is_convertible<T, Prop>::value), | ||
|  |         found, | ||
|  |         not_found | ||
|  |       >::type {}; | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_preferable_property : | ||
|  |       conditional< | ||
|  |         is_preferable<Prop>::value | ||
|  |           && (is_same<T, Prop>::value || is_convertible<T, Prop>::value), | ||
|  |         found, | ||
|  |         not_found | ||
|  |       >::type {}; | ||
|  | 
 | ||
|  |   struct find_context_as_property : | ||
|  |       conditional< | ||
|  |         is_context_as<Prop>::value, | ||
|  |         found, | ||
|  |         not_found | ||
|  |       >::type {}; | ||
|  | }; | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <std::size_t I, typename Head, typename... Tail> | ||
|  | struct supportable_properties<I, void(Head, Tail...)> | ||
|  | { | ||
|  |   template <typename T> | ||
|  |   struct is_valid_target : integral_constant<bool, | ||
|  |       ( | ||
|  |         supportable_properties<I, | ||
|  |           void(Head)>::template is_valid_target<T>::value | ||
|  |         && | ||
|  |         supportable_properties<I + 1, | ||
|  |           void(Tail...)>::template is_valid_target<T>::value | ||
|  |       ) | ||
|  |     > | ||
|  |   { | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_property : | ||
|  |       conditional< | ||
|  |         is_convertible<T, Head>::value, | ||
|  |         typename supportable_properties<I, void(Head)>::found, | ||
|  |         typename supportable_properties<I + 1, | ||
|  |             void(Tail...)>::template find_convertible_property<T> | ||
|  |       >::type {}; | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_requirable_property : | ||
|  |       conditional< | ||
|  |         is_requirable<Head>::value | ||
|  |           && is_convertible<T, Head>::value, | ||
|  |         typename supportable_properties<I, void(Head)>::found, | ||
|  |         typename supportable_properties<I + 1, | ||
|  |             void(Tail...)>::template find_convertible_requirable_property<T> | ||
|  |       >::type {}; | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_preferable_property : | ||
|  |       conditional< | ||
|  |         is_preferable<Head>::value | ||
|  |           && is_convertible<T, Head>::value, | ||
|  |         typename supportable_properties<I, void(Head)>::found, | ||
|  |         typename supportable_properties<I + 1, | ||
|  |             void(Tail...)>::template find_convertible_preferable_property<T> | ||
|  |       >::type {}; | ||
|  | 
 | ||
|  |   struct find_context_as_property : | ||
|  |       conditional< | ||
|  |         is_context_as<Head>::value, | ||
|  |         typename supportable_properties<I, void(Head)>::found, | ||
|  |         typename supportable_properties<I + 1, | ||
|  |             void(Tail...)>::find_context_as_property | ||
|  |       >::type {}; | ||
|  | }; | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF(n) \
 | ||
|  |   template <std::size_t I, \ | ||
|  |     typename Head, ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   struct supportable_properties<I, \ | ||
|  |       void(Head, ASIO_VARIADIC_TARGS(n))> \ | ||
|  |   { \ | ||
|  |     template <typename T> \ | ||
|  |     struct is_valid_target : integral_constant<bool, \ | ||
|  |         ( \ | ||
|  |           supportable_properties<I, \ | ||
|  |             void(Head)>::template is_valid_target<T>::value \ | ||
|  |           && \ | ||
|  |           supportable_properties<I + 1, \ | ||
|  |               void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |                 is_valid_target<T>::value \ | ||
|  |         ) \ | ||
|  |       > \ | ||
|  |     { \ | ||
|  |     }; \ | ||
|  |   \ | ||
|  |     template <typename T> \ | ||
|  |     struct find_convertible_property : \ | ||
|  |         conditional< \ | ||
|  |           is_convertible<T, Head>::value, \ | ||
|  |           typename supportable_properties<I, void(Head)>::found, \ | ||
|  |           typename supportable_properties<I + 1, \ | ||
|  |               void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |                 find_convertible_property<T> \ | ||
|  |         >::type {}; \ | ||
|  |   \ | ||
|  |     template <typename T> \ | ||
|  |     struct find_convertible_requirable_property : \ | ||
|  |         conditional< \ | ||
|  |           is_requirable<Head>::value \ | ||
|  |             && is_convertible<T, Head>::value, \ | ||
|  |           typename supportable_properties<I, void(Head)>::found, \ | ||
|  |           typename supportable_properties<I + 1, \ | ||
|  |               void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |                 find_convertible_requirable_property<T> \ | ||
|  |         >::type {}; \ | ||
|  |   \ | ||
|  |     template <typename T> \ | ||
|  |     struct find_convertible_preferable_property : \ | ||
|  |         conditional< \ | ||
|  |           is_preferable<Head>::value \ | ||
|  |             && is_convertible<T, Head>::value, \ | ||
|  |           typename supportable_properties<I, void(Head)>::found, \ | ||
|  |           typename supportable_properties<I + 1, \ | ||
|  |               void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |                 find_convertible_preferable_property<T> \ | ||
|  |         >::type {}; \ | ||
|  |   \ | ||
|  |     struct find_context_as_property : \ | ||
|  |         conditional< \ | ||
|  |           is_context_as<Head>::value, \ | ||
|  |           typename supportable_properties<I, void(Head)>::found, \ | ||
|  |           typename supportable_properties<I + 1, void( \ | ||
|  |             ASIO_VARIADIC_TARGS(n))>::find_context_as_property \ | ||
|  |         >::type {}; \ | ||
|  |   }; \ | ||
|  |   /**/ | ||
|  | ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF) | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename T, typename Props> | ||
|  | struct is_valid_target_executor : | ||
|  |   conditional< | ||
|  |     is_executor<T>::value, | ||
|  |     typename supportable_properties<0, Props>::template is_valid_target<T>, | ||
|  |     false_type | ||
|  |   >::type | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename Props> | ||
|  | struct is_valid_target_executor<int, Props> : false_type | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | class shared_target_executor | ||
|  | { | ||
|  | public: | ||
|  |   template <typename E> | ||
|  |   shared_target_executor(ASIO_MOVE_ARG(E) e, | ||
|  |       typename decay<E>::type*& target) | ||
|  |   { | ||
|  |     impl<typename decay<E>::type>* i = | ||
|  |       new impl<typename decay<E>::type>(ASIO_MOVE_CAST(E)(e)); | ||
|  |     target = &i->ex_; | ||
|  |     impl_ = i; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename E> | ||
|  |   shared_target_executor(std::nothrow_t, ASIO_MOVE_ARG(E) e, | ||
|  |       typename decay<E>::type*& target) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     impl<typename decay<E>::type>* i = | ||
|  |       new (std::nothrow) impl<typename decay<E>::type>( | ||
|  |         ASIO_MOVE_CAST(E)(e)); | ||
|  |     target = i ? &i->ex_ : 0; | ||
|  |     impl_ = i; | ||
|  |   } | ||
|  | 
 | ||
|  |   shared_target_executor( | ||
|  |       const shared_target_executor& other) ASIO_NOEXCEPT | ||
|  |     : impl_(other.impl_) | ||
|  |   { | ||
|  |     if (impl_) | ||
|  |       asio::detail::ref_count_up(impl_->ref_count_); | ||
|  |   } | ||
|  | 
 | ||
|  |   shared_target_executor& operator=( | ||
|  |       const shared_target_executor& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     impl_ = other.impl_; | ||
|  |     if (impl_) | ||
|  |       asio::detail::ref_count_up(impl_->ref_count_); | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_MOVE)
 | ||
|  |   shared_target_executor( | ||
|  |       shared_target_executor&& other) ASIO_NOEXCEPT | ||
|  |     : impl_(other.impl_) | ||
|  |   { | ||
|  |     other.impl_ = 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   shared_target_executor& operator=( | ||
|  |       shared_target_executor&& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     impl_ = other.impl_; | ||
|  |     other.impl_ = 0; | ||
|  |     return *this; | ||
|  |   } | ||
|  | #endif // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |   ~shared_target_executor() | ||
|  |   { | ||
|  |     if (impl_) | ||
|  |       if (asio::detail::ref_count_down(impl_->ref_count_)) | ||
|  |         delete impl_; | ||
|  |   } | ||
|  | 
 | ||
|  |   void* get() const ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return impl_ ? impl_->get() : 0; | ||
|  |   } | ||
|  | 
 | ||
|  | private: | ||
|  |   struct impl_base | ||
|  |   { | ||
|  |     impl_base() : ref_count_(1) {} | ||
|  |     virtual ~impl_base() {} | ||
|  |     virtual void* get() = 0; | ||
|  |     asio::detail::atomic_count ref_count_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   struct impl : impl_base | ||
|  |   { | ||
|  |     impl(Executor ex) : ex_(ASIO_MOVE_CAST(Executor)(ex)) {} | ||
|  |     virtual void* get() { return &ex_; } | ||
|  |     Executor ex_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   impl_base* impl_; | ||
|  | }; | ||
|  | 
 | ||
|  | class any_executor_base | ||
|  | { | ||
|  | public: | ||
|  |   any_executor_base() ASIO_NOEXCEPT | ||
|  |     : object_fns_(0), | ||
|  |       target_(0), | ||
|  |       target_fns_(0) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <ASIO_EXECUTION_EXECUTOR Executor> | ||
|  |   any_executor_base(Executor ex, false_type) | ||
|  |     : target_fns_(target_fns_table<Executor>( | ||
|  |           any_executor_base::query_blocking(ex, | ||
|  |             can_query<const Executor&, const execution::blocking_t&>()) | ||
|  |           == execution::blocking.always)) | ||
|  |   { | ||
|  |     any_executor_base::construct_object(ex, | ||
|  |         integral_constant<bool, | ||
|  |           sizeof(Executor) <= sizeof(object_type) | ||
|  |             && alignment_of<Executor>::value <= alignment_of<object_type>::value | ||
|  |         >()); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <ASIO_EXECUTION_EXECUTOR Executor> | ||
|  |   any_executor_base(std::nothrow_t, Executor ex, false_type) ASIO_NOEXCEPT | ||
|  |     : target_fns_(target_fns_table<Executor>( | ||
|  |           any_executor_base::query_blocking(ex, | ||
|  |             can_query<const Executor&, const execution::blocking_t&>()) | ||
|  |           == execution::blocking.always)) | ||
|  |   { | ||
|  |     any_executor_base::construct_object(std::nothrow, ex, | ||
|  |         integral_constant<bool, | ||
|  |           sizeof(Executor) <= sizeof(object_type) | ||
|  |             && alignment_of<Executor>::value <= alignment_of<object_type>::value | ||
|  |         >()); | ||
|  |     if (target_ == 0) | ||
|  |     { | ||
|  |       object_fns_ = 0; | ||
|  |       target_fns_ = 0; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   template <ASIO_EXECUTION_EXECUTOR Executor> | ||
|  |   any_executor_base(Executor other, true_type) | ||
|  |     : object_fns_(object_fns_table<shared_target_executor>()), | ||
|  |       target_fns_(other.target_fns_) | ||
|  |   { | ||
|  |     Executor* p = 0; | ||
|  |     new (&object_) shared_target_executor( | ||
|  |         ASIO_MOVE_CAST(Executor)(other), p); | ||
|  |     target_ = p->template target<void>(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <ASIO_EXECUTION_EXECUTOR Executor> | ||
|  |   any_executor_base(std::nothrow_t, | ||
|  |       Executor other, true_type) ASIO_NOEXCEPT | ||
|  |     : object_fns_(object_fns_table<shared_target_executor>()), | ||
|  |       target_fns_(other.target_fns_) | ||
|  |   { | ||
|  |     Executor* p = 0; | ||
|  |     new (&object_) shared_target_executor( | ||
|  |         std::nothrow, ASIO_MOVE_CAST(Executor)(other), p); | ||
|  |     if (p) | ||
|  |       target_ = p->template target<void>(); | ||
|  |     else | ||
|  |     { | ||
|  |       target_ = 0; | ||
|  |       object_fns_ = 0; | ||
|  |       target_fns_ = 0; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor_base(const any_executor_base& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (!!other) | ||
|  |     { | ||
|  |       object_fns_ = other.object_fns_; | ||
|  |       target_fns_ = other.target_fns_; | ||
|  |       object_fns_->copy(*this, other); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |       object_fns_ = 0; | ||
|  |       target_ = 0; | ||
|  |       target_fns_ = 0; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   ~any_executor_base() ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (!!*this) | ||
|  |       object_fns_->destroy(*this); | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor_base& operator=( | ||
|  |       const any_executor_base& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       if (!!*this) | ||
|  |         object_fns_->destroy(*this); | ||
|  |       if (!!other) | ||
|  |       { | ||
|  |         object_fns_ = other.object_fns_; | ||
|  |         target_fns_ = other.target_fns_; | ||
|  |         object_fns_->copy(*this, other); | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |         object_fns_ = 0; | ||
|  |         target_ = 0; | ||
|  |         target_fns_ = 0; | ||
|  |       } | ||
|  |     } | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor_base& operator=(nullptr_t) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (target_) | ||
|  |       object_fns_->destroy(*this); | ||
|  |     target_ = 0; | ||
|  |     object_fns_ = 0; | ||
|  |     target_fns_ = 0; | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |   any_executor_base(any_executor_base&& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (other.target_) | ||
|  |     { | ||
|  |       object_fns_ = other.object_fns_; | ||
|  |       target_fns_ = other.target_fns_; | ||
|  |       other.object_fns_ = 0; | ||
|  |       other.target_fns_ = 0; | ||
|  |       object_fns_->move(*this, other); | ||
|  |       other.target_ = 0; | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |       object_fns_ = 0; | ||
|  |       target_ = 0; | ||
|  |       target_fns_ = 0; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor_base& operator=( | ||
|  |       any_executor_base&& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       if (!!*this) | ||
|  |         object_fns_->destroy(*this); | ||
|  |       if (!!other) | ||
|  |       { | ||
|  |         object_fns_ = other.object_fns_; | ||
|  |         target_fns_ = other.target_fns_; | ||
|  |         other.object_fns_ = 0; | ||
|  |         other.target_fns_ = 0; | ||
|  |         object_fns_->move(*this, other); | ||
|  |         other.target_ = 0; | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |         object_fns_ = 0; | ||
|  |         target_ = 0; | ||
|  |         target_fns_ = 0; | ||
|  |       } | ||
|  |     } | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |   void swap(any_executor_base& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       any_executor_base tmp(ASIO_MOVE_CAST(any_executor_base)(other)); | ||
|  |       other = ASIO_MOVE_CAST(any_executor_base)(*this); | ||
|  |       *this = ASIO_MOVE_CAST(any_executor_base)(tmp); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename F> | ||
|  |   void execute(ASIO_MOVE_ARG(F) f) const | ||
|  |   { | ||
|  |     if (target_) | ||
|  |     { | ||
|  |       if (target_fns_->blocking_execute != 0) | ||
|  |       { | ||
|  |         asio::detail::non_const_lvalue<F> f2(f); | ||
|  |         target_fns_->blocking_execute(*this, function_view(f2.value)); | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |         target_fns_->execute(*this, | ||
|  |             function(ASIO_MOVE_CAST(F)(f), std::allocator<void>())); | ||
|  |       } | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |       bad_executor ex; | ||
|  |       asio::detail::throw_exception(ex); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   Executor* target() | ||
|  |   { | ||
|  |     return target_ && (is_same<Executor, void>::value | ||
|  |         || target_fns_->target_type() == target_type_ex<Executor>()) | ||
|  |       ? static_cast<Executor*>(target_) : 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   const Executor* target() const | ||
|  |   { | ||
|  |     return target_ && (is_same<Executor, void>::value | ||
|  |         || target_fns_->target_type() == target_type_ex<Executor>()) | ||
|  |       ? static_cast<const Executor*>(target_) : 0; | ||
|  |   } | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_TYPEID)
 | ||
|  |   const std::type_info& target_type() const | ||
|  |   { | ||
|  |     return target_ ? target_fns_->target_type() : typeid(void); | ||
|  |   } | ||
|  | #else // !defined(ASIO_NO_TYPEID)
 | ||
|  |   const void* target_type() const | ||
|  |   { | ||
|  |     return target_ ? target_fns_->target_type() : 0; | ||
|  |   } | ||
|  | #endif // !defined(ASIO_NO_TYPEID)
 | ||
|  | 
 | ||
|  |   struct unspecified_bool_type_t {}; | ||
|  |   typedef void (*unspecified_bool_type)(unspecified_bool_type_t); | ||
|  |   static void unspecified_bool_true(unspecified_bool_type_t) {} | ||
|  | 
 | ||
|  |   operator unspecified_bool_type() const ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return target_ ? &any_executor_base::unspecified_bool_true : 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   bool operator!() const ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return target_ == 0; | ||
|  |   } | ||
|  | 
 | ||
|  | protected: | ||
|  |   bool equality_helper(const any_executor_base& other) const ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (target_ == other.target_) | ||
|  |       return true; | ||
|  |     if (target_ && !other.target_) | ||
|  |       return false; | ||
|  |     if (!target_ && other.target_) | ||
|  |       return false; | ||
|  |     if (target_fns_ != other.target_fns_) | ||
|  |       return false; | ||
|  |     return target_fns_->equal(*this, other); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex> | ||
|  |   Ex& object() | ||
|  |   { | ||
|  |     return *static_cast<Ex*>(static_cast<void*>(&object_)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex> | ||
|  |   const Ex& object() const | ||
|  |   { | ||
|  |     return *static_cast<const Ex*>(static_cast<const void*>(&object_)); | ||
|  |   } | ||
|  | 
 | ||
|  |   struct object_fns | ||
|  |   { | ||
|  |     void (*destroy)(any_executor_base&); | ||
|  |     void (*copy)(any_executor_base&, const any_executor_base&); | ||
|  |     void (*move)(any_executor_base&, any_executor_base&); | ||
|  |     const void* (*target)(const any_executor_base&); | ||
|  |   }; | ||
|  | 
 | ||
|  |   static void destroy_shared(any_executor_base& ex) | ||
|  |   { | ||
|  |     typedef shared_target_executor type; | ||
|  |     ex.object<type>().~type(); | ||
|  |   } | ||
|  | 
 | ||
|  |   static void copy_shared(any_executor_base& ex1, const any_executor_base& ex2) | ||
|  |   { | ||
|  |     typedef shared_target_executor type; | ||
|  |     new (&ex1.object_) type(ex2.object<type>()); | ||
|  |     ex1.target_ = ex2.target_; | ||
|  |   } | ||
|  | 
 | ||
|  |   static void move_shared(any_executor_base& ex1, any_executor_base& ex2) | ||
|  |   { | ||
|  |     typedef shared_target_executor type; | ||
|  |     new (&ex1.object_) type(ASIO_MOVE_CAST(type)(ex2.object<type>())); | ||
|  |     ex1.target_ = ex2.target_; | ||
|  |     ex2.object<type>().~type(); | ||
|  |   } | ||
|  | 
 | ||
|  |   static const void* target_shared(const any_executor_base& ex) | ||
|  |   { | ||
|  |     typedef shared_target_executor type; | ||
|  |     return ex.object<type>().get(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Obj> | ||
|  |   static const object_fns* object_fns_table( | ||
|  |       typename enable_if< | ||
|  |         is_same<Obj, shared_target_executor>::value | ||
|  |       >::type* = 0) | ||
|  |   { | ||
|  |     static const object_fns fns = | ||
|  |     { | ||
|  |       &any_executor_base::destroy_shared, | ||
|  |       &any_executor_base::copy_shared, | ||
|  |       &any_executor_base::move_shared, | ||
|  |       &any_executor_base::target_shared | ||
|  |     }; | ||
|  |     return &fns; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Obj> | ||
|  |   static void destroy_object(any_executor_base& ex) | ||
|  |   { | ||
|  |     ex.object<Obj>().~Obj(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Obj> | ||
|  |   static void copy_object(any_executor_base& ex1, const any_executor_base& ex2) | ||
|  |   { | ||
|  |     new (&ex1.object_) Obj(ex2.object<Obj>()); | ||
|  |     ex1.target_ = &ex1.object<Obj>(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Obj> | ||
|  |   static void move_object(any_executor_base& ex1, any_executor_base& ex2) | ||
|  |   { | ||
|  |     new (&ex1.object_) Obj(ASIO_MOVE_CAST(Obj)(ex2.object<Obj>())); | ||
|  |     ex1.target_ = &ex1.object<Obj>(); | ||
|  |     ex2.object<Obj>().~Obj(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Obj> | ||
|  |   static const void* target_object(const any_executor_base& ex) | ||
|  |   { | ||
|  |     return &ex.object<Obj>(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Obj> | ||
|  |   static const object_fns* object_fns_table( | ||
|  |       typename enable_if< | ||
|  |         !is_same<Obj, void>::value | ||
|  |           && !is_same<Obj, shared_target_executor>::value | ||
|  |       >::type* = 0) | ||
|  |   { | ||
|  |     static const object_fns fns = | ||
|  |     { | ||
|  |       &any_executor_base::destroy_object<Obj>, | ||
|  |       &any_executor_base::copy_object<Obj>, | ||
|  |       &any_executor_base::move_object<Obj>, | ||
|  |       &any_executor_base::target_object<Obj> | ||
|  |     }; | ||
|  |     return &fns; | ||
|  |   } | ||
|  | 
 | ||
|  |   typedef asio::detail::executor_function function; | ||
|  |   typedef asio::detail::executor_function_view function_view; | ||
|  | 
 | ||
|  |   struct target_fns | ||
|  |   { | ||
|  | #if !defined(ASIO_NO_TYPEID)
 | ||
|  |     const std::type_info& (*target_type)(); | ||
|  | #else // !defined(ASIO_NO_TYPEID)
 | ||
|  |     const void* (*target_type)(); | ||
|  | #endif // !defined(ASIO_NO_TYPEID)
 | ||
|  |     bool (*equal)(const any_executor_base&, const any_executor_base&); | ||
|  |     void (*execute)(const any_executor_base&, ASIO_MOVE_ARG(function)); | ||
|  |     void (*blocking_execute)(const any_executor_base&, function_view); | ||
|  |   }; | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_TYPEID)
 | ||
|  |   template <typename Ex> | ||
|  |   static const std::type_info& target_type_ex() | ||
|  |   { | ||
|  |     return typeid(Ex); | ||
|  |   } | ||
|  | #else // !defined(ASIO_NO_TYPEID)
 | ||
|  |   template <typename Ex> | ||
|  |   static const void* target_type_ex() | ||
|  |   { | ||
|  |     static int unique_id; | ||
|  |     return &unique_id; | ||
|  |   } | ||
|  | #endif // !defined(ASIO_NO_TYPEID)
 | ||
|  | 
 | ||
|  |   template <typename Ex> | ||
|  |   static bool equal_ex(const any_executor_base& ex1, | ||
|  |       const any_executor_base& ex2) | ||
|  |   { | ||
|  |     const Ex* p1 = ex1.target<Ex>(); | ||
|  |     const Ex* p2 = ex2.target<Ex>(); | ||
|  |     ASIO_ASSUME(p1 != 0 && p2 != 0); | ||
|  |     return *p1 == *p2; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex> | ||
|  |   static void execute_ex(const any_executor_base& ex, | ||
|  |       ASIO_MOVE_ARG(function) f) | ||
|  |   { | ||
|  |     const Ex* p = ex.target<Ex>(); | ||
|  |     ASIO_ASSUME(p != 0); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     p->execute(ASIO_MOVE_CAST(function)(f)); | ||
|  | #else // defined(ASIO_NO_DEPRECATED)
 | ||
|  |     execution::execute(*p, ASIO_MOVE_CAST(function)(f)); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex> | ||
|  |   static void blocking_execute_ex(const any_executor_base& ex, function_view f) | ||
|  |   { | ||
|  |     const Ex* p = ex.target<Ex>(); | ||
|  |     ASIO_ASSUME(p != 0); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     p->execute(f); | ||
|  | #else // defined(ASIO_NO_DEPRECATED)
 | ||
|  |     execution::execute(*p, f); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex> | ||
|  |   static const target_fns* target_fns_table(bool is_always_blocking, | ||
|  |       typename enable_if< | ||
|  |         !is_same<Ex, void>::value | ||
|  |       >::type* = 0) | ||
|  |   { | ||
|  |     static const target_fns fns_with_execute = | ||
|  |     { | ||
|  |       &any_executor_base::target_type_ex<Ex>, | ||
|  |       &any_executor_base::equal_ex<Ex>, | ||
|  |       &any_executor_base::execute_ex<Ex>, | ||
|  |       0 | ||
|  |     }; | ||
|  | 
 | ||
|  |     static const target_fns fns_with_blocking_execute = | ||
|  |     { | ||
|  |       &any_executor_base::target_type_ex<Ex>, | ||
|  |       &any_executor_base::equal_ex<Ex>, | ||
|  |       0, | ||
|  |       &any_executor_base::blocking_execute_ex<Ex> | ||
|  |     }; | ||
|  | 
 | ||
|  |     return is_always_blocking ? &fns_with_blocking_execute : &fns_with_execute; | ||
|  |   } | ||
|  | 
 | ||
|  | #if defined(ASIO_MSVC)
 | ||
|  | # pragma warning (push)
 | ||
|  | # pragma warning (disable:4702)
 | ||
|  | #endif // defined(ASIO_MSVC)
 | ||
|  | 
 | ||
|  |   static void query_fn_void(void*, const void*, const void*) | ||
|  |   { | ||
|  |     bad_executor ex; | ||
|  |     asio::detail::throw_exception(ex); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void*, const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         asio::can_query<const Ex&, const Prop&>::value | ||
|  |           && is_same<typename Prop::polymorphic_query_result_type, void>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     asio::query(*static_cast<const Ex*>(ex), | ||
|  |         *static_cast<const Prop*>(prop)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void*, const void*, const void*, | ||
|  |       typename enable_if< | ||
|  |         !asio::can_query<const Ex&, const Prop&>::value | ||
|  |           && is_same<typename Prop::polymorphic_query_result_type, void>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void* result, const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         asio::can_query<const Ex&, const Prop&>::value | ||
|  |           && !is_same<typename Prop::polymorphic_query_result_type, void>::value | ||
|  |           && is_reference<typename Prop::polymorphic_query_result_type>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     *static_cast<typename remove_reference< | ||
|  |       typename Prop::polymorphic_query_result_type>::type**>(result) | ||
|  |         = &static_cast<typename Prop::polymorphic_query_result_type>( | ||
|  |             asio::query(*static_cast<const Ex*>(ex), | ||
|  |               *static_cast<const Prop*>(prop))); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void*, const void*, const void*, | ||
|  |       typename enable_if< | ||
|  |         !asio::can_query<const Ex&, const Prop&>::value | ||
|  |           && !is_same<typename Prop::polymorphic_query_result_type, void>::value | ||
|  |           && is_reference<typename Prop::polymorphic_query_result_type>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     std::terminate(); // Combination should not be possible.
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void* result, const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         asio::can_query<const Ex&, const Prop&>::value | ||
|  |           && !is_same<typename Prop::polymorphic_query_result_type, void>::value | ||
|  |           && is_scalar<typename Prop::polymorphic_query_result_type>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     *static_cast<typename Prop::polymorphic_query_result_type*>(result) | ||
|  |       = static_cast<typename Prop::polymorphic_query_result_type>( | ||
|  |           asio::query(*static_cast<const Ex*>(ex), | ||
|  |             *static_cast<const Prop*>(prop))); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void* result, const void*, const void*, | ||
|  |       typename enable_if< | ||
|  |         !asio::can_query<const Ex&, const Prop&>::value | ||
|  |           && !is_same<typename Prop::polymorphic_query_result_type, void>::value | ||
|  |           && is_scalar<typename Prop::polymorphic_query_result_type>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     *static_cast<typename Prop::polymorphic_query_result_type*>(result) | ||
|  |       = typename Prop::polymorphic_query_result_type(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void* result, const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         asio::can_query<const Ex&, const Prop&>::value | ||
|  |           && !is_same<typename Prop::polymorphic_query_result_type, void>::value | ||
|  |           && !is_reference<typename Prop::polymorphic_query_result_type>::value | ||
|  |           && !is_scalar<typename Prop::polymorphic_query_result_type>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     *static_cast<typename Prop::polymorphic_query_result_type**>(result) | ||
|  |       = new typename Prop::polymorphic_query_result_type( | ||
|  |           asio::query(*static_cast<const Ex*>(ex), | ||
|  |             *static_cast<const Prop*>(prop))); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_non_void(void* result, const void*, const void*, ...) | ||
|  |   { | ||
|  |     *static_cast<typename Prop::polymorphic_query_result_type**>(result) | ||
|  |       = new typename Prop::polymorphic_query_result_type(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_impl(void* result, const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         is_same<Ex, void>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     query_fn_void(result, ex, prop); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn_impl(void* result, const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         !is_same<Ex, void>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     query_fn_non_void<Ex, Prop>(result, ex, prop, 0); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Ex, class Prop> | ||
|  |   static void query_fn(void* result, const void* ex, const void* prop) | ||
|  |   { | ||
|  |     query_fn_impl<Ex, Prop>(result, ex, prop, 0); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly require_fn_impl(const void*, const void*, | ||
|  |       typename enable_if< | ||
|  |         is_same<Ex, void>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     bad_executor ex; | ||
|  |     asio::detail::throw_exception(ex); | ||
|  |     return Poly(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly require_fn_impl(const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         !is_same<Ex, void>::value && Prop::is_requirable | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     return asio::require(*static_cast<const Ex*>(ex), | ||
|  |         *static_cast<const Prop*>(prop)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly require_fn_impl(const void*, const void*, ...) | ||
|  |   { | ||
|  |     return Poly(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly require_fn(const void* ex, const void* prop) | ||
|  |   { | ||
|  |     return require_fn_impl<Poly, Ex, Prop>(ex, prop, 0); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly prefer_fn_impl(const void*, const void*, | ||
|  |       typename enable_if< | ||
|  |         is_same<Ex, void>::value | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     bad_executor ex; | ||
|  |     asio::detail::throw_exception(ex); | ||
|  |     return Poly(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly prefer_fn_impl(const void* ex, const void* prop, | ||
|  |       typename enable_if< | ||
|  |         !is_same<Ex, void>::value && Prop::is_preferable | ||
|  |       >::type*) | ||
|  |   { | ||
|  |     return asio::prefer(*static_cast<const Ex*>(ex), | ||
|  |         *static_cast<const Prop*>(prop)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly prefer_fn_impl(const void*, const void*, ...) | ||
|  |   { | ||
|  |     return Poly(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly, typename Ex, class Prop> | ||
|  |   static Poly prefer_fn(const void* ex, const void* prop) | ||
|  |   { | ||
|  |     return prefer_fn_impl<Poly, Ex, Prop>(ex, prop, 0); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Poly> | ||
|  |   struct prop_fns | ||
|  |   { | ||
|  |     void (*query)(void*, const void*, const void*); | ||
|  |     Poly (*require)(const void*, const void*); | ||
|  |     Poly (*prefer)(const void*, const void*); | ||
|  |   }; | ||
|  | 
 | ||
|  | #if defined(ASIO_MSVC)
 | ||
|  | # pragma warning (pop)
 | ||
|  | #endif // defined(ASIO_MSVC)
 | ||
|  | 
 | ||
|  | private: | ||
|  |   template <typename Executor> | ||
|  |   static execution::blocking_t query_blocking(const Executor& ex, true_type) | ||
|  |   { | ||
|  |     return asio::query(ex, execution::blocking); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   static execution::blocking_t query_blocking(const Executor&, false_type) | ||
|  |   { | ||
|  |     return execution::blocking_t(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   void construct_object(Executor& ex, true_type) | ||
|  |   { | ||
|  |     object_fns_ = object_fns_table<Executor>(); | ||
|  |     target_ = new (&object_) Executor(ASIO_MOVE_CAST(Executor)(ex)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   void construct_object(Executor& ex, false_type) | ||
|  |   { | ||
|  |     object_fns_ = object_fns_table<shared_target_executor>(); | ||
|  |     Executor* p = 0; | ||
|  |     new (&object_) shared_target_executor( | ||
|  |         ASIO_MOVE_CAST(Executor)(ex), p); | ||
|  |     target_ = p; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   void construct_object(std::nothrow_t, | ||
|  |       Executor& ex, true_type) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     object_fns_ = object_fns_table<Executor>(); | ||
|  |     target_ = new (&object_) Executor(ASIO_MOVE_CAST(Executor)(ex)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   void construct_object(std::nothrow_t, | ||
|  |       Executor& ex, false_type) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     object_fns_ = object_fns_table<shared_target_executor>(); | ||
|  |     Executor* p = 0; | ||
|  |     new (&object_) shared_target_executor( | ||
|  |         std::nothrow, ASIO_MOVE_CAST(Executor)(ex), p); | ||
|  |     target_ = p; | ||
|  |   } | ||
|  | 
 | ||
|  | /*private:*/public: | ||
|  | //  template <typename...> friend class any_executor;
 | ||
|  | 
 | ||
|  |   typedef aligned_storage< | ||
|  |       sizeof(asio::detail::shared_ptr<void>) + sizeof(void*), | ||
|  |       alignment_of<asio::detail::shared_ptr<void> >::value | ||
|  |     >::type object_type; | ||
|  | 
 | ||
|  |   object_type object_; | ||
|  |   const object_fns* object_fns_; | ||
|  |   void* target_; | ||
|  |   const target_fns* target_fns_; | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename Derived, typename Property, typename = void> | ||
|  | struct any_executor_context | ||
|  | { | ||
|  | }; | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_TS_EXECUTORS)
 | ||
|  | 
 | ||
|  | template <typename Derived, typename Property> | ||
|  | struct any_executor_context<Derived, Property, | ||
|  |     typename enable_if<Property::value>::type> | ||
|  | { | ||
|  |   typename Property::query_result_type context() const | ||
|  |   { | ||
|  |     return static_cast<const Derived*>(this)->query(typename Property::type()); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | #endif // !defined(ASIO_NO_TS_EXECUTORS)
 | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | 
 | ||
|  | template <> | ||
|  | class any_executor<> : public detail::any_executor_base | ||
|  | { | ||
|  | public: | ||
|  |   any_executor() ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base() | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor(nullptr_t) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base() | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   any_executor(Executor ex, | ||
|  |       typename enable_if< | ||
|  |         conditional< | ||
|  |           !is_same<Executor, any_executor>::value | ||
|  |             && !is_base_of<detail::any_executor_base, Executor>::value, | ||
|  |           is_executor<Executor>, | ||
|  |           false_type | ||
|  |         >::type::value | ||
|  |       >::type* = 0) | ||
|  |     : detail::any_executor_base( | ||
|  |         ASIO_MOVE_CAST(Executor)(ex), false_type()) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   any_executor(std::nothrow_t, Executor ex, | ||
|  |       typename enable_if< | ||
|  |         conditional< | ||
|  |           !is_same<Executor, any_executor>::value | ||
|  |             && !is_base_of<detail::any_executor_base, Executor>::value, | ||
|  |           is_executor<Executor>, | ||
|  |           false_type | ||
|  |         >::type::value | ||
|  |       >::type* = 0) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base(std::nothrow, | ||
|  |         ASIO_MOVE_CAST(Executor)(ex), false_type()) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  |   template <typename... OtherSupportableProperties> | ||
|  |   any_executor(any_executor<OtherSupportableProperties...> other) | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename... OtherSupportableProperties> | ||
|  |   any_executor(std::nothrow_t, | ||
|  |       any_executor<OtherSupportableProperties...> other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  |   template <typename U0, typename U1, typename U2, typename U3, | ||
|  |       typename U4, typename U5, typename U6, typename U7> | ||
|  |   any_executor(any_executor<U0, U1, U2, U3, U4, U5, U6, U7> other) | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename U0, typename U1, typename U2, typename U3, | ||
|  |       typename U4, typename U5, typename U6, typename U7> | ||
|  |   any_executor(std::nothrow_t, | ||
|  |       any_executor<U0, U1, U2, U3, U4, U5, U6, U7> other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  |   any_executor(const any_executor& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor(std::nothrow_t, const any_executor& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       detail::any_executor_base::operator=( | ||
|  |           static_cast<const detail::any_executor_base&>(other)); | ||
|  |     } | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     detail::any_executor_base::operator=(p); | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |   any_executor(any_executor&& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<any_executor_base&&>( | ||
|  |           static_cast<any_executor_base&>(other))) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<any_executor_base&&>( | ||
|  |           static_cast<any_executor_base&>(other))) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       detail::any_executor_base::operator=( | ||
|  |           static_cast<detail::any_executor_base&&>( | ||
|  |             static_cast<detail::any_executor_base&>(other))); | ||
|  |     } | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |   void swap(any_executor& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     detail::any_executor_base::swap( | ||
|  |         static_cast<detail::any_executor_base&>(other)); | ||
|  |   } | ||
|  | 
 | ||
|  |   using detail::any_executor_base::execute; | ||
|  |   using detail::any_executor_base::target; | ||
|  |   using detail::any_executor_base::target_type; | ||
|  |   using detail::any_executor_base::operator unspecified_bool_type; | ||
|  |   using detail::any_executor_base::operator!; | ||
|  | 
 | ||
|  |   bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return any_executor_base::equality_helper(other); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor1, typename AnyExecutor2> | ||
|  |   friend typename enable_if< | ||
|  |     is_base_of<any_executor, AnyExecutor1>::value | ||
|  |       || is_base_of<any_executor, AnyExecutor2>::value, | ||
|  |     bool | ||
|  |   >::type operator==(const AnyExecutor1& a, | ||
|  |       const AnyExecutor2& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return static_cast<const any_executor&>(a).equality_helper(b); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !a; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !b; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor1, typename AnyExecutor2> | ||
|  |   friend typename enable_if< | ||
|  |     is_base_of<any_executor, AnyExecutor1>::value | ||
|  |       || is_base_of<any_executor, AnyExecutor2>::value, | ||
|  |     bool | ||
|  |   >::type operator!=(const AnyExecutor1& a, | ||
|  |       const AnyExecutor2& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !static_cast<const any_executor&>(a).equality_helper(b); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !!a; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !!b; | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | inline void swap(any_executor<>& a, any_executor<>& b) ASIO_NOEXCEPT | ||
|  | { | ||
|  |   return a.swap(b); | ||
|  | } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename... SupportableProperties> | ||
|  | class any_executor : | ||
|  |   public detail::any_executor_base, | ||
|  |   public detail::any_executor_context< | ||
|  |     any_executor<SupportableProperties...>, | ||
|  |       typename detail::supportable_properties< | ||
|  |         0, void(SupportableProperties...)>::find_context_as_property> | ||
|  | { | ||
|  | public: | ||
|  |   any_executor() ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base(), | ||
|  |       prop_fns_(prop_fns_table<void>()) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor(nullptr_t) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base(), | ||
|  |       prop_fns_(prop_fns_table<void>()) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   any_executor(Executor ex, | ||
|  |       typename enable_if< | ||
|  |         conditional< | ||
|  |           !is_same<Executor, any_executor>::value | ||
|  |             && !is_base_of<detail::any_executor_base, Executor>::value, | ||
|  |           detail::is_valid_target_executor< | ||
|  |             Executor, void(SupportableProperties...)>, | ||
|  |           false_type | ||
|  |         >::type::value | ||
|  |       >::type* = 0) | ||
|  |     : detail::any_executor_base( | ||
|  |         ASIO_MOVE_CAST(Executor)(ex), false_type()), | ||
|  |       prop_fns_(prop_fns_table<Executor>()) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Executor> | ||
|  |   any_executor(std::nothrow_t, Executor ex, | ||
|  |       typename enable_if< | ||
|  |         conditional< | ||
|  |           !is_same<Executor, any_executor>::value | ||
|  |             && !is_base_of<detail::any_executor_base, Executor>::value, | ||
|  |           detail::is_valid_target_executor< | ||
|  |             Executor, void(SupportableProperties...)>, | ||
|  |           false_type | ||
|  |         >::type::value | ||
|  |       >::type* = 0) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base(std::nothrow, | ||
|  |         ASIO_MOVE_CAST(Executor)(ex), false_type()), | ||
|  |       prop_fns_(prop_fns_table<Executor>()) | ||
|  |   { | ||
|  |     if (this->template target<void>() == 0) | ||
|  |       prop_fns_ = prop_fns_table<void>(); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename... OtherSupportableProperties> | ||
|  |   any_executor(any_executor<OtherSupportableProperties...> other, | ||
|  |       typename enable_if< | ||
|  |         conditional< | ||
|  |           !is_same< | ||
|  |             any_executor<OtherSupportableProperties...>, | ||
|  |             any_executor | ||
|  |           >::value, | ||
|  |           typename detail::supportable_properties< | ||
|  |             0, void(SupportableProperties...)>::template is_valid_target< | ||
|  |               any_executor<OtherSupportableProperties...> >, | ||
|  |           false_type | ||
|  |         >::type::value | ||
|  |       >::type* = 0) | ||
|  |     : detail::any_executor_base(ASIO_MOVE_CAST( | ||
|  |           any_executor<OtherSupportableProperties...>)(other), true_type()), | ||
|  |       prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...> >()) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename... OtherSupportableProperties> | ||
|  |   any_executor(std::nothrow_t, | ||
|  |       any_executor<OtherSupportableProperties...> other, | ||
|  |       typename enable_if< | ||
|  |         conditional< | ||
|  |           !is_same< | ||
|  |             any_executor<OtherSupportableProperties...>, | ||
|  |             any_executor | ||
|  |           >::value, | ||
|  |           typename detail::supportable_properties< | ||
|  |             0, void(SupportableProperties...)>::template is_valid_target< | ||
|  |               any_executor<OtherSupportableProperties...> >, | ||
|  |           false_type | ||
|  |         >::type::value | ||
|  |       >::type* = 0) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base(std::nothrow, ASIO_MOVE_CAST( | ||
|  |           any_executor<OtherSupportableProperties...>)(other), true_type()), | ||
|  |       prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...> >()) | ||
|  |   { | ||
|  |     if (this->template target<void>() == 0) | ||
|  |       prop_fns_ = prop_fns_table<void>(); | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor(const any_executor& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)), | ||
|  |       prop_fns_(other.prop_fns_) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor(std::nothrow_t, const any_executor& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<const detail::any_executor_base&>(other)), | ||
|  |       prop_fns_(other.prop_fns_) | ||
|  |   { | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       prop_fns_ = other.prop_fns_; | ||
|  |       detail::any_executor_base::operator=( | ||
|  |           static_cast<const detail::any_executor_base&>(other)); | ||
|  |     } | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     prop_fns_ = prop_fns_table<void>(); | ||
|  |     detail::any_executor_base::operator=(p); | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |   any_executor(any_executor&& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<any_executor_base&&>( | ||
|  |           static_cast<any_executor_base&>(other))), | ||
|  |       prop_fns_(other.prop_fns_) | ||
|  |   { | ||
|  |     other.prop_fns_ = prop_fns_table<void>(); | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT | ||
|  |     : detail::any_executor_base( | ||
|  |         static_cast<any_executor_base&&>( | ||
|  |           static_cast<any_executor_base&>(other))), | ||
|  |       prop_fns_(other.prop_fns_) | ||
|  |   { | ||
|  |     other.prop_fns_ = prop_fns_table<void>(); | ||
|  |   } | ||
|  | 
 | ||
|  |   any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       prop_fns_ = other.prop_fns_; | ||
|  |       detail::any_executor_base::operator=( | ||
|  |           static_cast<detail::any_executor_base&&>( | ||
|  |             static_cast<detail::any_executor_base&>(other))); | ||
|  |     } | ||
|  |     return *this; | ||
|  |   } | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |   void swap(any_executor& other) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     if (this != &other) | ||
|  |     { | ||
|  |       detail::any_executor_base::swap( | ||
|  |           static_cast<detail::any_executor_base&>(other)); | ||
|  |       const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_; | ||
|  |       other.prop_fns_ = prop_fns_; | ||
|  |       prop_fns_ = tmp_prop_fns; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   using detail::any_executor_base::execute; | ||
|  |   using detail::any_executor_base::target; | ||
|  |   using detail::any_executor_base::target_type; | ||
|  |   using detail::any_executor_base::operator unspecified_bool_type; | ||
|  |   using detail::any_executor_base::operator!; | ||
|  | 
 | ||
|  |   bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return any_executor_base::equality_helper(other); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor1, typename AnyExecutor2> | ||
|  |   friend typename enable_if< | ||
|  |     is_base_of<any_executor, AnyExecutor1>::value | ||
|  |       || is_base_of<any_executor, AnyExecutor2>::value, | ||
|  |     bool | ||
|  |   >::type operator==(const AnyExecutor1& a, | ||
|  |       const AnyExecutor2& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return static_cast<const any_executor&>(a).equality_helper(b); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !a; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !b; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor1, typename AnyExecutor2> | ||
|  |   friend typename enable_if< | ||
|  |     is_base_of<any_executor, AnyExecutor1>::value | ||
|  |       || is_base_of<any_executor, AnyExecutor2>::value, | ||
|  |     bool | ||
|  |   >::type operator!=(const AnyExecutor1& a, | ||
|  |       const AnyExecutor2& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !static_cast<const any_executor&>(a).equality_helper(b); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !!a; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename AnyExecutor> | ||
|  |   friend typename enable_if< | ||
|  |     is_same<AnyExecutor, any_executor>::value, | ||
|  |     bool | ||
|  |   >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return !!b; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_property : | ||
|  |       detail::supportable_properties< | ||
|  |         0, void(SupportableProperties...)>::template | ||
|  |           find_convertible_property<T> {}; | ||
|  | 
 | ||
|  |   template <typename Property> | ||
|  |   void query(const Property& p, | ||
|  |       typename enable_if< | ||
|  |         is_same< | ||
|  |           typename find_convertible_property<Property>::query_result_type, | ||
|  |           void | ||
|  |         >::value | ||
|  |       >::type* = 0) const | ||
|  |   { | ||
|  |     typedef find_convertible_property<Property> found; | ||
|  |     prop_fns_[found::index].query(0, object_fns_->target(*this), | ||
|  |         &static_cast<const typename found::type&>(p)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Property> | ||
|  |   typename find_convertible_property<Property>::query_result_type | ||
|  |   query(const Property& p, | ||
|  |       typename enable_if< | ||
|  |         !is_same< | ||
|  |           typename find_convertible_property<Property>::query_result_type, | ||
|  |           void | ||
|  |         >::value | ||
|  |         && | ||
|  |         is_reference< | ||
|  |           typename find_convertible_property<Property>::query_result_type | ||
|  |         >::value | ||
|  |       >::type* = 0) const | ||
|  |   { | ||
|  |     typedef find_convertible_property<Property> found; | ||
|  |     typename remove_reference< | ||
|  |       typename found::query_result_type>::type* result = 0; | ||
|  |     prop_fns_[found::index].query(&result, object_fns_->target(*this), | ||
|  |         &static_cast<const typename found::type&>(p)); | ||
|  |     return *result; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Property> | ||
|  |   typename find_convertible_property<Property>::query_result_type | ||
|  |   query(const Property& p, | ||
|  |       typename enable_if< | ||
|  |         !is_same< | ||
|  |           typename find_convertible_property<Property>::query_result_type, | ||
|  |           void | ||
|  |         >::value | ||
|  |         && | ||
|  |         is_scalar< | ||
|  |           typename find_convertible_property<Property>::query_result_type | ||
|  |         >::value | ||
|  |       >::type* = 0) const | ||
|  |   { | ||
|  |     typedef find_convertible_property<Property> found; | ||
|  |     typename found::query_result_type result; | ||
|  |     prop_fns_[found::index].query(&result, object_fns_->target(*this), | ||
|  |         &static_cast<const typename found::type&>(p)); | ||
|  |     return result; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Property> | ||
|  |   typename find_convertible_property<Property>::query_result_type | ||
|  |   query(const Property& p, | ||
|  |       typename enable_if< | ||
|  |         !is_same< | ||
|  |           typename find_convertible_property<Property>::query_result_type, | ||
|  |           void | ||
|  |         >::value | ||
|  |         && | ||
|  |         !is_reference< | ||
|  |           typename find_convertible_property<Property>::query_result_type | ||
|  |         >::value | ||
|  |         && | ||
|  |         !is_scalar< | ||
|  |           typename find_convertible_property<Property>::query_result_type | ||
|  |         >::value | ||
|  |       >::type* = 0) const | ||
|  |   { | ||
|  |     typedef find_convertible_property<Property> found; | ||
|  |     typename found::query_result_type* result; | ||
|  |     prop_fns_[found::index].query(&result, object_fns_->target(*this), | ||
|  |         &static_cast<const typename found::type&>(p)); | ||
|  |     return *asio::detail::scoped_ptr< | ||
|  |       typename found::query_result_type>(result); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_requirable_property : | ||
|  |       detail::supportable_properties< | ||
|  |         0, void(SupportableProperties...)>::template | ||
|  |           find_convertible_requirable_property<T> {}; | ||
|  | 
 | ||
|  |   template <typename Property> | ||
|  |   any_executor require(const Property& p, | ||
|  |       typename enable_if< | ||
|  |         find_convertible_requirable_property<Property>::value | ||
|  |       >::type* = 0) const | ||
|  |   { | ||
|  |     typedef find_convertible_requirable_property<Property> found; | ||
|  |     return prop_fns_[found::index].require(object_fns_->target(*this), | ||
|  |         &static_cast<const typename found::type&>(p)); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename T> | ||
|  |   struct find_convertible_preferable_property : | ||
|  |       detail::supportable_properties< | ||
|  |         0, void(SupportableProperties...)>::template | ||
|  |           find_convertible_preferable_property<T> {}; | ||
|  | 
 | ||
|  |   template <typename Property> | ||
|  |   any_executor prefer(const Property& p, | ||
|  |       typename enable_if< | ||
|  |         find_convertible_preferable_property<Property>::value | ||
|  |       >::type* = 0) const | ||
|  |   { | ||
|  |     typedef find_convertible_preferable_property<Property> found; | ||
|  |     return prop_fns_[found::index].prefer(object_fns_->target(*this), | ||
|  |         &static_cast<const typename found::type&>(p)); | ||
|  |   } | ||
|  | 
 | ||
|  | //private:
 | ||
|  |   template <typename Ex> | ||
|  |   static const prop_fns<any_executor>* prop_fns_table() | ||
|  |   { | ||
|  |     static const prop_fns<any_executor> fns[] = | ||
|  |     { | ||
|  |       { | ||
|  |         &detail::any_executor_base::query_fn< | ||
|  |             Ex, SupportableProperties>, | ||
|  |         &detail::any_executor_base::require_fn< | ||
|  |             any_executor, Ex, SupportableProperties>, | ||
|  |         &detail::any_executor_base::prefer_fn< | ||
|  |             any_executor, Ex, SupportableProperties> | ||
|  |       }... | ||
|  |     }; | ||
|  |     return fns; | ||
|  |   } | ||
|  | 
 | ||
|  |   const prop_fns<any_executor>* prop_fns_; | ||
|  | }; | ||
|  | 
 | ||
|  | template <typename... SupportableProperties> | ||
|  | inline void swap(any_executor<SupportableProperties...>& a, | ||
|  |     any_executor<SupportableProperties...>& b) ASIO_NOEXCEPT | ||
|  | { | ||
|  |   return a.swap(b); | ||
|  | } | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_##n | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1 \
 | ||
|  |   {  \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T1>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T1>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T1> \ | ||
|  |   } | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2 \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1, \ | ||
|  |   { \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T2>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T2>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T2> \ | ||
|  |   } | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3 \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2, \ | ||
|  |   { \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T3>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T3>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T3> \ | ||
|  |   } | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4 \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3, \ | ||
|  |   { \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T4>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T4>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T4> \ | ||
|  |   } | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5 \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4, \ | ||
|  |   { \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T5>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T5>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T5> \ | ||
|  |   } | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6 \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5, \ | ||
|  |   { \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T6>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T6>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T6> \ | ||
|  |   } | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7 \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6, \ | ||
|  |   { \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T7>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T7>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T7> \ | ||
|  |   } | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8 \
 | ||
|  |   ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7, \ | ||
|  |   { \ | ||
|  |     &detail::any_executor_base::query_fn<Ex, T8>, \ | ||
|  |     &detail::any_executor_base::require_fn<any_executor, Ex, T8>, \ | ||
|  |     &detail::any_executor_base::prefer_fn<any_executor, Ex, T8> \ | ||
|  |   } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  | # define ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \
 | ||
|  |   any_executor(any_executor&& other) ASIO_NOEXCEPT \ | ||
|  |     : detail::any_executor_base( \ | ||
|  |         static_cast<any_executor_base&&>( \ | ||
|  |           static_cast<any_executor_base&>(other))), \ | ||
|  |       prop_fns_(other.prop_fns_) \ | ||
|  |   { \ | ||
|  |     other.prop_fns_ = prop_fns_table<void>(); \ | ||
|  |   } \ | ||
|  |   \ | ||
|  |   any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT \ | ||
|  |     : detail::any_executor_base( \ | ||
|  |         static_cast<any_executor_base&&>( \ | ||
|  |           static_cast<any_executor_base&>(other))), \ | ||
|  |       prop_fns_(other.prop_fns_) \ | ||
|  |   { \ | ||
|  |     other.prop_fns_ = prop_fns_table<void>(); \ | ||
|  |   } \ | ||
|  |   \ | ||
|  |   any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT \ | ||
|  |   { \ | ||
|  |     if (this != &other) \ | ||
|  |     { \ | ||
|  |       prop_fns_ = other.prop_fns_; \ | ||
|  |       detail::any_executor_base::operator=( \ | ||
|  |           static_cast<detail::any_executor_base&&>( \ | ||
|  |             static_cast<detail::any_executor_base&>(other))); \ | ||
|  |     } \ | ||
|  |     return *this; \ | ||
|  |   } \ | ||
|  |   /**/ | ||
|  | #else // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  | # define ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_DEF(n) \
 | ||
|  |   template <ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   class any_executor<ASIO_VARIADIC_TARGS(n)> : \ | ||
|  |     public detail::any_executor_base, \ | ||
|  |     public detail::any_executor_context< \ | ||
|  |       any_executor<ASIO_VARIADIC_TARGS(n)>, \ | ||
|  |         typename detail::supportable_properties< \ | ||
|  |           0, void(ASIO_VARIADIC_TARGS(n))>::find_context_as_property> \ | ||
|  |   { \ | ||
|  |   public: \ | ||
|  |     any_executor() ASIO_NOEXCEPT \ | ||
|  |       : detail::any_executor_base(), \ | ||
|  |         prop_fns_(prop_fns_table<void>()) \ | ||
|  |     { \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     any_executor(nullptr_t) ASIO_NOEXCEPT \ | ||
|  |       : detail::any_executor_base(), \ | ||
|  |         prop_fns_(prop_fns_table<void>()) \ | ||
|  |     { \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <ASIO_EXECUTION_EXECUTOR Executor> \ | ||
|  |     any_executor(Executor ex, \ | ||
|  |         typename enable_if< \ | ||
|  |           conditional< \ | ||
|  |             !is_same<Executor, any_executor>::value \ | ||
|  |               && !is_base_of<detail::any_executor_base, Executor>::value, \ | ||
|  |             detail::is_valid_target_executor< \ | ||
|  |               Executor, void(ASIO_VARIADIC_TARGS(n))>, \ | ||
|  |             false_type \ | ||
|  |           >::type::value \ | ||
|  |         >::type* = 0) \ | ||
|  |       : detail::any_executor_base(ASIO_MOVE_CAST( \ | ||
|  |             Executor)(ex), false_type()), \ | ||
|  |         prop_fns_(prop_fns_table<Executor>()) \ | ||
|  |     { \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <ASIO_EXECUTION_EXECUTOR Executor> \ | ||
|  |     any_executor(std::nothrow_t, Executor ex, \ | ||
|  |         typename enable_if< \ | ||
|  |           conditional< \ | ||
|  |             !is_same<Executor, any_executor>::value \ | ||
|  |               && !is_base_of<detail::any_executor_base, Executor>::value, \ | ||
|  |             detail::is_valid_target_executor< \ | ||
|  |               Executor, void(ASIO_VARIADIC_TARGS(n))>, \ | ||
|  |             false_type \ | ||
|  |           >::type::value \ | ||
|  |         >::type* = 0) ASIO_NOEXCEPT \ | ||
|  |       : detail::any_executor_base(std::nothrow, \ | ||
|  |           ASIO_MOVE_CAST(Executor)(ex), false_type()), \ | ||
|  |         prop_fns_(prop_fns_table<Executor>()) \ | ||
|  |     { \ | ||
|  |       if (this->template target<void>() == 0) \ | ||
|  |         prop_fns_ = prop_fns_table<void>(); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     any_executor(const any_executor& other) ASIO_NOEXCEPT \ | ||
|  |       : detail::any_executor_base( \ | ||
|  |           static_cast<const detail::any_executor_base&>(other)), \ | ||
|  |         prop_fns_(other.prop_fns_) \ | ||
|  |     { \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     any_executor(std::nothrow_t, \ | ||
|  |         const any_executor& other) ASIO_NOEXCEPT \ | ||
|  |       : detail::any_executor_base( \ | ||
|  |           static_cast<const detail::any_executor_base&>(other)), \ | ||
|  |         prop_fns_(other.prop_fns_) \ | ||
|  |     { \ | ||
|  |       if (this->template target<void>() == 0) \ | ||
|  |         prop_fns_ = prop_fns_table<void>(); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     any_executor(any_executor<> other) \ | ||
|  |       : detail::any_executor_base(ASIO_MOVE_CAST( \ | ||
|  |             any_executor<>)(other), true_type()), \ | ||
|  |         prop_fns_(prop_fns_table<any_executor<> >()) \ | ||
|  |     { \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     any_executor(std::nothrow_t, any_executor<> other) ASIO_NOEXCEPT \ | ||
|  |       : detail::any_executor_base(std::nothrow, \ | ||
|  |           ASIO_MOVE_CAST(any_executor<>)(other), true_type()), \ | ||
|  |         prop_fns_(prop_fns_table<any_executor<> >()) \ | ||
|  |     { \ | ||
|  |       if (this->template target<void>() == 0) \ | ||
|  |         prop_fns_ = prop_fns_table<void>(); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename OtherAnyExecutor> \ | ||
|  |     any_executor(OtherAnyExecutor other, \ | ||
|  |         typename enable_if< \ | ||
|  |           conditional< \ | ||
|  |             !is_same<OtherAnyExecutor, any_executor>::value \ | ||
|  |               && is_base_of<detail::any_executor_base, \ | ||
|  |                 OtherAnyExecutor>::value, \ | ||
|  |             typename detail::supportable_properties< \ | ||
|  |               0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |                 is_valid_target<OtherAnyExecutor>, \ | ||
|  |             false_type \ | ||
|  |           >::type::value \ | ||
|  |         >::type* = 0) \ | ||
|  |       : detail::any_executor_base(ASIO_MOVE_CAST( \ | ||
|  |             OtherAnyExecutor)(other), true_type()), \ | ||
|  |         prop_fns_(prop_fns_table<OtherAnyExecutor>()) \ | ||
|  |     { \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename OtherAnyExecutor> \ | ||
|  |     any_executor(std::nothrow_t, OtherAnyExecutor other, \ | ||
|  |         typename enable_if< \ | ||
|  |           conditional< \ | ||
|  |             !is_same<OtherAnyExecutor, any_executor>::value \ | ||
|  |               && is_base_of<detail::any_executor_base, \ | ||
|  |                 OtherAnyExecutor>::value, \ | ||
|  |             typename detail::supportable_properties< \ | ||
|  |               0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |                 is_valid_target<OtherAnyExecutor>, \ | ||
|  |             false_type \ | ||
|  |           >::type::value \ | ||
|  |         >::type* = 0) ASIO_NOEXCEPT \ | ||
|  |       : detail::any_executor_base(std::nothrow, \ | ||
|  |           ASIO_MOVE_CAST(OtherAnyExecutor)(other), true_type()), \ | ||
|  |         prop_fns_(prop_fns_table<OtherAnyExecutor>()) \ | ||
|  |     { \ | ||
|  |       if (this->template target<void>() == 0) \ | ||
|  |         prop_fns_ = prop_fns_table<void>(); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       if (this != &other) \ | ||
|  |       { \ | ||
|  |         prop_fns_ = other.prop_fns_; \ | ||
|  |         detail::any_executor_base::operator=( \ | ||
|  |             static_cast<const detail::any_executor_base&>(other)); \ | ||
|  |       } \ | ||
|  |       return *this; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       prop_fns_ = prop_fns_table<void>(); \ | ||
|  |       detail::any_executor_base::operator=(p); \ | ||
|  |       return *this; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \ | ||
|  |     \ | ||
|  |     void swap(any_executor& other) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       if (this != &other) \ | ||
|  |       { \ | ||
|  |         detail::any_executor_base::swap( \ | ||
|  |             static_cast<detail::any_executor_base&>(other)); \ | ||
|  |         const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_; \ | ||
|  |         other.prop_fns_ = prop_fns_; \ | ||
|  |         prop_fns_ = tmp_prop_fns; \ | ||
|  |       } \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     using detail::any_executor_base::execute; \ | ||
|  |     using detail::any_executor_base::target; \ | ||
|  |     using detail::any_executor_base::target_type; \ | ||
|  |     using detail::any_executor_base::operator unspecified_bool_type; \ | ||
|  |     using detail::any_executor_base::operator!; \ | ||
|  |     \ | ||
|  |     bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       return any_executor_base::equality_helper(other); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename AnyExecutor1, typename AnyExecutor2> \ | ||
|  |     friend typename enable_if< \ | ||
|  |       is_base_of<any_executor, AnyExecutor1>::value \ | ||
|  |         || is_base_of<any_executor, AnyExecutor2>::value, \ | ||
|  |       bool \ | ||
|  |     >::type operator==(const AnyExecutor1& a, \ | ||
|  |         const AnyExecutor2& b) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       return static_cast<const any_executor&>(a).equality_helper(b); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename AnyExecutor> \ | ||
|  |     friend typename enable_if< \ | ||
|  |       is_same<AnyExecutor, any_executor>::value, \ | ||
|  |       bool \ | ||
|  |     >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       return !a; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename AnyExecutor> \ | ||
|  |     friend typename enable_if< \ | ||
|  |       is_same<AnyExecutor, any_executor>::value, \ | ||
|  |       bool \ | ||
|  |     >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       return !b; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename AnyExecutor1, typename AnyExecutor2> \ | ||
|  |     friend typename enable_if< \ | ||
|  |       is_base_of<any_executor, AnyExecutor1>::value \ | ||
|  |         || is_base_of<any_executor, AnyExecutor2>::value, \ | ||
|  |       bool \ | ||
|  |     >::type operator!=(const AnyExecutor1& a, \ | ||
|  |         const AnyExecutor2& b) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       return !static_cast<const any_executor&>(a).equality_helper(b); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename AnyExecutor> \ | ||
|  |     friend typename enable_if< \ | ||
|  |       is_same<AnyExecutor, any_executor>::value, \ | ||
|  |       bool \ | ||
|  |     >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       return !!a; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename AnyExecutor> \ | ||
|  |     friend typename enable_if< \ | ||
|  |       is_same<AnyExecutor, any_executor>::value, \ | ||
|  |       bool \ | ||
|  |     >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT \ | ||
|  |     { \ | ||
|  |       return !!b; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename T> \ | ||
|  |     struct find_convertible_property : \ | ||
|  |         detail::supportable_properties< \ | ||
|  |           0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |             find_convertible_property<T> {}; \ | ||
|  |     \ | ||
|  |     template <typename Property> \ | ||
|  |     void query(const Property& p, \ | ||
|  |         typename enable_if< \ | ||
|  |           is_same< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type, \ | ||
|  |             void \ | ||
|  |           >::value \ | ||
|  |         >::type* = 0) const \ | ||
|  |     { \ | ||
|  |       typedef find_convertible_property<Property> found; \ | ||
|  |       prop_fns_[found::index].query(0, object_fns_->target(*this), \ | ||
|  |           &static_cast<const typename found::type&>(p)); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename Property> \ | ||
|  |     typename find_convertible_property<Property>::query_result_type \ | ||
|  |     query(const Property& p, \ | ||
|  |         typename enable_if< \ | ||
|  |           !is_same< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type, \ | ||
|  |             void \ | ||
|  |           >::value \ | ||
|  |           && \ | ||
|  |           is_reference< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type \ | ||
|  |           >::value \ | ||
|  |         >::type* = 0) const \ | ||
|  |     { \ | ||
|  |       typedef find_convertible_property<Property> found; \ | ||
|  |       typename remove_reference< \ | ||
|  |         typename found::query_result_type>::type* result; \ | ||
|  |       prop_fns_[found::index].query(&result, object_fns_->target(*this), \ | ||
|  |           &static_cast<const typename found::type&>(p)); \ | ||
|  |       return *result; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename Property> \ | ||
|  |     typename find_convertible_property<Property>::query_result_type \ | ||
|  |     query(const Property& p, \ | ||
|  |         typename enable_if< \ | ||
|  |           !is_same< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type, \ | ||
|  |             void \ | ||
|  |           >::value \ | ||
|  |           && \ | ||
|  |           is_scalar< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type \ | ||
|  |           >::value \ | ||
|  |         >::type* = 0) const \ | ||
|  |     { \ | ||
|  |       typedef find_convertible_property<Property> found; \ | ||
|  |       typename found::query_result_type result; \ | ||
|  |       prop_fns_[found::index].query(&result, object_fns_->target(*this), \ | ||
|  |           &static_cast<const typename found::type&>(p)); \ | ||
|  |       return result; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename Property> \ | ||
|  |     typename find_convertible_property<Property>::query_result_type \ | ||
|  |     query(const Property& p, \ | ||
|  |         typename enable_if< \ | ||
|  |           !is_same< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type, \ | ||
|  |             void \ | ||
|  |           >::value \ | ||
|  |           && \ | ||
|  |           !is_reference< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type \ | ||
|  |           >::value \ | ||
|  |           && \ | ||
|  |           !is_scalar< \ | ||
|  |             typename find_convertible_property<Property>::query_result_type \ | ||
|  |           >::value \ | ||
|  |         >::type* = 0) const \ | ||
|  |     { \ | ||
|  |       typedef find_convertible_property<Property> found; \ | ||
|  |       typename found::query_result_type* result; \ | ||
|  |       prop_fns_[found::index].query(&result, object_fns_->target(*this), \ | ||
|  |           &static_cast<const typename found::type&>(p)); \ | ||
|  |       return *asio::detail::scoped_ptr< \ | ||
|  |         typename found::query_result_type>(result); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename T> \ | ||
|  |     struct find_convertible_requirable_property : \ | ||
|  |         detail::supportable_properties< \ | ||
|  |           0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |             find_convertible_requirable_property<T> {}; \ | ||
|  |     \ | ||
|  |     template <typename Property> \ | ||
|  |     any_executor require(const Property& p, \ | ||
|  |         typename enable_if< \ | ||
|  |           find_convertible_requirable_property<Property>::value \ | ||
|  |         >::type* = 0) const \ | ||
|  |     { \ | ||
|  |       typedef find_convertible_requirable_property<Property> found; \ | ||
|  |       return prop_fns_[found::index].require(object_fns_->target(*this), \ | ||
|  |           &static_cast<const typename found::type&>(p)); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename T> \ | ||
|  |     struct find_convertible_preferable_property : \ | ||
|  |         detail::supportable_properties< \ | ||
|  |           0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |             find_convertible_preferable_property<T> {}; \ | ||
|  |     \ | ||
|  |     template <typename Property> \ | ||
|  |     any_executor prefer(const Property& p, \ | ||
|  |         typename enable_if< \ | ||
|  |           find_convertible_preferable_property<Property>::value \ | ||
|  |         >::type* = 0) const \ | ||
|  |     { \ | ||
|  |       typedef find_convertible_preferable_property<Property> found; \ | ||
|  |       return prop_fns_[found::index].prefer(object_fns_->target(*this), \ | ||
|  |           &static_cast<const typename found::type&>(p)); \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     template <typename Ex> \ | ||
|  |     static const prop_fns<any_executor>* prop_fns_table() \ | ||
|  |     { \ | ||
|  |       static const prop_fns<any_executor> fns[] = \ | ||
|  |       { \ | ||
|  |         ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \ | ||
|  |       }; \ | ||
|  |       return fns; \ | ||
|  |     } \ | ||
|  |     \ | ||
|  |     const prop_fns<any_executor>* prop_fns_; \ | ||
|  |     typedef detail::supportable_properties<0, \ | ||
|  |         void(ASIO_VARIADIC_TARGS(n))> supportable_properties_type; \ | ||
|  |   }; \ | ||
|  |   \ | ||
|  |   template <ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   inline void swap(any_executor<ASIO_VARIADIC_TARGS(n)>& a, \ | ||
|  |       any_executor<ASIO_VARIADIC_TARGS(n)>& b) ASIO_NOEXCEPT \ | ||
|  |   { \ | ||
|  |     return a.swap(b); \ | ||
|  |   } \ | ||
|  |   /**/ | ||
|  |   ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_DEF) | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_DEF
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7
 | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8
 | ||
|  | 
 | ||
|  | #endif // if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | } // namespace execution
 | ||
|  | namespace traits { | ||
|  | 
 | ||
|  | #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename... SupportableProperties> | ||
|  | struct equality_comparable<execution::any_executor<SupportableProperties...> > | ||
|  | { | ||
|  |   static const bool is_valid = true; | ||
|  |   static const bool is_noexcept = true; | ||
|  | }; | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <> | ||
|  | struct equality_comparable<execution::any_executor<> > | ||
|  | { | ||
|  |   static const bool is_valid = true; | ||
|  |   static const bool is_noexcept = true; | ||
|  | }; | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF(n) \
 | ||
|  |   template <ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   struct equality_comparable< \ | ||
|  |       execution::any_executor<ASIO_VARIADIC_TARGS(n)> > \ | ||
|  |   { \ | ||
|  |     static const bool is_valid = true; \ | ||
|  |     static const bool is_noexcept = true; \ | ||
|  |   }; \ | ||
|  |   /**/ | ||
|  |   ASIO_VARIADIC_GENERATE( | ||
|  |       ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF) | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
 | ||
|  | 
 | ||
|  | #if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename F, typename... SupportableProperties> | ||
|  | struct execute_member<execution::any_executor<SupportableProperties...>, F> | ||
|  | { | ||
|  |   static const bool is_valid = true; | ||
|  |   static const bool is_noexcept = false; | ||
|  |   typedef void result_type; | ||
|  | }; | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename F> | ||
|  | struct execute_member<execution::any_executor<>, F> | ||
|  | { | ||
|  |   static const bool is_valid = true; | ||
|  |   static const bool is_noexcept = false; | ||
|  |   typedef void result_type; | ||
|  | }; | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF(n) \
 | ||
|  |   template <typename F, ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   struct execute_member< \ | ||
|  |       execution::any_executor<ASIO_VARIADIC_TARGS(n)>, F> \ | ||
|  |   { \ | ||
|  |     static const bool is_valid = true; \ | ||
|  |     static const bool is_noexcept = false; \ | ||
|  |     typedef void result_type; \ | ||
|  |   }; \ | ||
|  |   /**/ | ||
|  |   ASIO_VARIADIC_GENERATE( | ||
|  |       ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF) | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
 | ||
|  | 
 | ||
|  | #if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename Prop, typename... SupportableProperties> | ||
|  | struct query_member< | ||
|  |     execution::any_executor<SupportableProperties...>, Prop, | ||
|  |     typename enable_if< | ||
|  |       execution::detail::supportable_properties< | ||
|  |         0, void(SupportableProperties...)>::template | ||
|  |           find_convertible_property<Prop>::value | ||
|  |     >::type> | ||
|  | { | ||
|  |   static const bool is_valid = true; | ||
|  |   static const bool is_noexcept = false; | ||
|  |   typedef typename execution::detail::supportable_properties< | ||
|  |       0, void(SupportableProperties...)>::template | ||
|  |         find_convertible_property<Prop>::query_result_type result_type; | ||
|  | }; | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF(n) \
 | ||
|  |   template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   struct query_member< \ | ||
|  |       execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \ | ||
|  |       typename enable_if< \ | ||
|  |         execution::detail::supportable_properties< \ | ||
|  |           0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |             find_convertible_property<Prop>::value \ | ||
|  |     >::type> \ | ||
|  |   { \ | ||
|  |     static const bool is_valid = true; \ | ||
|  |     static const bool is_noexcept = false; \ | ||
|  |     typedef typename execution::detail::supportable_properties< \ | ||
|  |         0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |           find_convertible_property<Prop>::query_result_type result_type; \ | ||
|  |   }; \ | ||
|  |   /**/ | ||
|  |   ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF) | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
 | ||
|  | 
 | ||
|  | #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename Prop, typename... SupportableProperties> | ||
|  | struct require_member< | ||
|  |     execution::any_executor<SupportableProperties...>, Prop, | ||
|  |     typename enable_if< | ||
|  |       execution::detail::supportable_properties< | ||
|  |         0, void(SupportableProperties...)>::template | ||
|  |           find_convertible_requirable_property<Prop>::value | ||
|  |     >::type> | ||
|  | { | ||
|  |   static const bool is_valid = true; | ||
|  |   static const bool is_noexcept = false; | ||
|  |   typedef execution::any_executor<SupportableProperties...> result_type; | ||
|  | }; | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF(n) \
 | ||
|  |   template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   struct require_member< \ | ||
|  |       execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \ | ||
|  |       typename enable_if< \ | ||
|  |         execution::detail::supportable_properties< \ | ||
|  |           0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |             find_convertible_requirable_property<Prop>::value \ | ||
|  |       >::type> \ | ||
|  |   { \ | ||
|  |     static const bool is_valid = true; \ | ||
|  |     static const bool is_noexcept = false; \ | ||
|  |     typedef execution::any_executor<ASIO_VARIADIC_TARGS(n)> result_type; \ | ||
|  |   }; \ | ||
|  |   /**/ | ||
|  |   ASIO_VARIADIC_GENERATE( | ||
|  |       ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF) | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
 | ||
|  | 
 | ||
|  | #if !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
 | ||
|  | #if defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | template <typename Prop, typename... SupportableProperties> | ||
|  | struct prefer_member< | ||
|  |     execution::any_executor<SupportableProperties...>, Prop, | ||
|  |     typename enable_if< | ||
|  |       execution::detail::supportable_properties< | ||
|  |         0, void(SupportableProperties...)>::template | ||
|  |           find_convertible_preferable_property<Prop>::value | ||
|  |     >::type> | ||
|  | { | ||
|  |   static const bool is_valid = true; | ||
|  |   static const bool is_noexcept = false; | ||
|  |   typedef execution::any_executor<SupportableProperties...> result_type; | ||
|  | }; | ||
|  | 
 | ||
|  | #else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | 
 | ||
|  | #define ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF(n) \
 | ||
|  |   template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \ | ||
|  |   struct prefer_member< \ | ||
|  |       execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \ | ||
|  |       typename enable_if< \ | ||
|  |         execution::detail::supportable_properties< \ | ||
|  |           0, void(ASIO_VARIADIC_TARGS(n))>::template \ | ||
|  |             find_convertible_preferable_property<Prop>::value \ | ||
|  |       >::type> \ | ||
|  |   { \ | ||
|  |     static const bool is_valid = true; \ | ||
|  |     static const bool is_noexcept = false; \ | ||
|  |     typedef execution::any_executor<ASIO_VARIADIC_TARGS(n)> result_type; \ | ||
|  |   }; \ | ||
|  |   /**/ | ||
|  |   ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF) | ||
|  | #undef ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF
 | ||
|  | 
 | ||
|  | #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
 | ||
|  | #endif // !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)
 | ||
|  | 
 | ||
|  | } // namespace traits
 | ||
|  | 
 | ||
|  | #endif // defined(GENERATING_DOCUMENTATION)
 | ||
|  | 
 | ||
|  | } // namespace asio
 | ||
|  | 
 | ||
|  | #include "asio/detail/pop_options.hpp"
 | ||
|  | 
 | ||
|  | #endif // ASIO_EXECUTION_ANY_EXECUTOR_HPP
 |