960 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			960 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | //
 | ||
|  | // impl/connect.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_IMPL_CONNECT_HPP
 | ||
|  | #define ASIO_IMPL_CONNECT_HPP
 | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | # pragma once
 | ||
|  | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 | ||
|  | 
 | ||
|  | #include <algorithm>
 | ||
|  | #include "asio/associator.hpp"
 | ||
|  | #include "asio/detail/base_from_cancellation_state.hpp"
 | ||
|  | #include "asio/detail/bind_handler.hpp"
 | ||
|  | #include "asio/detail/handler_alloc_helpers.hpp"
 | ||
|  | #include "asio/detail/handler_cont_helpers.hpp"
 | ||
|  | #include "asio/detail/handler_invoke_helpers.hpp"
 | ||
|  | #include "asio/detail/handler_tracking.hpp"
 | ||
|  | #include "asio/detail/handler_type_requirements.hpp"
 | ||
|  | #include "asio/detail/non_const_lvalue.hpp"
 | ||
|  | #include "asio/detail/throw_error.hpp"
 | ||
|  | #include "asio/detail/type_traits.hpp"
 | ||
|  | #include "asio/error.hpp"
 | ||
|  | #include "asio/post.hpp"
 | ||
|  | 
 | ||
|  | #include "asio/detail/push_options.hpp"
 | ||
|  | 
 | ||
|  | namespace asio { | ||
|  | 
 | ||
|  | namespace detail | ||
|  | { | ||
|  |   struct default_connect_condition | ||
|  |   { | ||
|  |     template <typename Endpoint> | ||
|  |     bool operator()(const asio::error_code&, const Endpoint&) | ||
|  |     { | ||
|  |       return true; | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Iterator> | ||
|  |   inline typename Protocol::endpoint deref_connect_result( | ||
|  |       Iterator iter, asio::error_code& ec) | ||
|  |   { | ||
|  |     return ec ? typename Protocol::endpoint() : *iter; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename T, typename Iterator> | ||
|  |   struct legacy_connect_condition_helper : T | ||
|  |   { | ||
|  |     typedef char (*fallback_func_type)(...); | ||
|  |     operator fallback_func_type() const; | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename R, typename Arg1, typename Arg2, typename Iterator> | ||
|  |   struct legacy_connect_condition_helper<R (*)(Arg1, Arg2), Iterator> | ||
|  |   { | ||
|  |     R operator()(Arg1, Arg2) const; | ||
|  |     char operator()(...) const; | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename T, typename Iterator> | ||
|  |   struct is_legacy_connect_condition | ||
|  |   { | ||
|  |     static char asio_connect_condition_check(char); | ||
|  |     static char (&asio_connect_condition_check(Iterator))[2]; | ||
|  | 
 | ||
|  |     static const bool value = | ||
|  |       sizeof(asio_connect_condition_check( | ||
|  |         (declval<legacy_connect_condition_helper<T, Iterator> >())( | ||
|  |           declval<const asio::error_code>(), | ||
|  |           declval<const Iterator>()))) != 1; | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename ConnectCondition, typename Iterator> | ||
|  |   inline Iterator call_connect_condition(ConnectCondition& connect_condition, | ||
|  |       const asio::error_code& ec, Iterator next, Iterator end, | ||
|  |       typename enable_if<is_legacy_connect_condition< | ||
|  |         ConnectCondition, Iterator>::value>::type* = 0) | ||
|  |   { | ||
|  |     if (next != end) | ||
|  |       return connect_condition(ec, next); | ||
|  |     return end; | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename ConnectCondition, typename Iterator> | ||
|  |   inline Iterator call_connect_condition(ConnectCondition& connect_condition, | ||
|  |       const asio::error_code& ec, Iterator next, Iterator end, | ||
|  |       typename enable_if<!is_legacy_connect_condition< | ||
|  |         ConnectCondition, Iterator>::value>::type* = 0) | ||
|  |   { | ||
|  |     for (;next != end; ++next) | ||
|  |       if (connect_condition(ec, *next)) | ||
|  |         return next; | ||
|  |     return end; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, typename EndpointSequence> | ||
|  | typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, | ||
|  |     const EndpointSequence& endpoints, | ||
|  |     typename constraint<is_endpoint_sequence< | ||
|  |         EndpointSequence>::value>::type) | ||
|  | { | ||
|  |   asio::error_code ec; | ||
|  |   typename Protocol::endpoint result = connect(s, endpoints, ec); | ||
|  |   asio::detail::throw_error(ec, "connect"); | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, typename EndpointSequence> | ||
|  | typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, | ||
|  |     const EndpointSequence& endpoints, asio::error_code& ec, | ||
|  |     typename constraint<is_endpoint_sequence< | ||
|  |         EndpointSequence>::value>::type) | ||
|  | { | ||
|  |   return detail::deref_connect_result<Protocol>( | ||
|  |       connect(s, endpoints.begin(), endpoints.end(), | ||
|  |         detail::default_connect_condition(), ec), ec); | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_DEPRECATED)
 | ||
|  | template <typename Protocol, typename Executor, typename Iterator> | ||
|  | Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, | ||
|  |     typename constraint<!is_endpoint_sequence<Iterator>::value>::type) | ||
|  | { | ||
|  |   asio::error_code ec; | ||
|  |   Iterator result = connect(s, begin, ec); | ||
|  |   asio::detail::throw_error(ec, "connect"); | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, typename Iterator> | ||
|  | inline Iterator connect(basic_socket<Protocol, Executor>& s, | ||
|  |     Iterator begin, asio::error_code& ec, | ||
|  |     typename constraint<!is_endpoint_sequence<Iterator>::value>::type) | ||
|  | { | ||
|  |   return connect(s, begin, Iterator(), detail::default_connect_condition(), ec); | ||
|  | } | ||
|  | #endif // !defined(ASIO_NO_DEPRECATED)
 | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, typename Iterator> | ||
|  | Iterator connect(basic_socket<Protocol, Executor>& s, | ||
|  |     Iterator begin, Iterator end) | ||
|  | { | ||
|  |   asio::error_code ec; | ||
|  |   Iterator result = connect(s, begin, end, ec); | ||
|  |   asio::detail::throw_error(ec, "connect"); | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, typename Iterator> | ||
|  | inline Iterator connect(basic_socket<Protocol, Executor>& s, | ||
|  |     Iterator begin, Iterator end, asio::error_code& ec) | ||
|  | { | ||
|  |   return connect(s, begin, end, detail::default_connect_condition(), ec); | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename EndpointSequence, typename ConnectCondition> | ||
|  | typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, | ||
|  |     const EndpointSequence& endpoints, ConnectCondition connect_condition, | ||
|  |     typename constraint<is_endpoint_sequence< | ||
|  |         EndpointSequence>::value>::type) | ||
|  | { | ||
|  |   asio::error_code ec; | ||
|  |   typename Protocol::endpoint result = connect( | ||
|  |       s, endpoints, connect_condition, ec); | ||
|  |   asio::detail::throw_error(ec, "connect"); | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename EndpointSequence, typename ConnectCondition> | ||
|  | typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, | ||
|  |     const EndpointSequence& endpoints, ConnectCondition connect_condition, | ||
|  |     asio::error_code& ec, | ||
|  |     typename constraint<is_endpoint_sequence< | ||
|  |         EndpointSequence>::value>::type) | ||
|  | { | ||
|  |   return detail::deref_connect_result<Protocol>( | ||
|  |       connect(s, endpoints.begin(), endpoints.end(), | ||
|  |         connect_condition, ec), ec); | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_DEPRECATED)
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename Iterator, typename ConnectCondition> | ||
|  | Iterator connect(basic_socket<Protocol, Executor>& s, | ||
|  |     Iterator begin, ConnectCondition connect_condition, | ||
|  |     typename constraint<!is_endpoint_sequence<Iterator>::value>::type) | ||
|  | { | ||
|  |   asio::error_code ec; | ||
|  |   Iterator result = connect(s, begin, connect_condition, ec); | ||
|  |   asio::detail::throw_error(ec, "connect"); | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename Iterator, typename ConnectCondition> | ||
|  | inline Iterator connect(basic_socket<Protocol, Executor>& s, | ||
|  |     Iterator begin, ConnectCondition connect_condition, | ||
|  |     asio::error_code& ec, | ||
|  |     typename constraint<!is_endpoint_sequence<Iterator>::value>::type) | ||
|  | { | ||
|  |   return connect(s, begin, Iterator(), connect_condition, ec); | ||
|  | } | ||
|  | #endif // !defined(ASIO_NO_DEPRECATED)
 | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename Iterator, typename ConnectCondition> | ||
|  | Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, | ||
|  |     Iterator end, ConnectCondition connect_condition) | ||
|  | { | ||
|  |   asio::error_code ec; | ||
|  |   Iterator result = connect(s, begin, end, connect_condition, ec); | ||
|  |   asio::detail::throw_error(ec, "connect"); | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename Iterator, typename ConnectCondition> | ||
|  | Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, | ||
|  |     Iterator end, ConnectCondition connect_condition, | ||
|  |     asio::error_code& ec) | ||
|  | { | ||
|  |   ec = asio::error_code(); | ||
|  | 
 | ||
|  |   for (Iterator iter = begin; iter != end; ++iter) | ||
|  |   { | ||
|  |     iter = (detail::call_connect_condition(connect_condition, ec, iter, end)); | ||
|  |     if (iter != end) | ||
|  |     { | ||
|  |       s.close(ec); | ||
|  |       s.connect(*iter, ec); | ||
|  |       if (!ec) | ||
|  |         return iter; | ||
|  |     } | ||
|  |     else | ||
|  |       break; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (!ec) | ||
|  |     ec = asio::error::not_found; | ||
|  | 
 | ||
|  |   return end; | ||
|  | } | ||
|  | 
 | ||
|  | namespace detail | ||
|  | { | ||
|  |   // Enable the empty base class optimisation for the connect condition.
 | ||
|  |   template <typename ConnectCondition> | ||
|  |   class base_from_connect_condition | ||
|  |   { | ||
|  |   protected: | ||
|  |     explicit base_from_connect_condition( | ||
|  |         const ConnectCondition& connect_condition) | ||
|  |       : connect_condition_(connect_condition) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename Iterator> | ||
|  |     void check_condition(const asio::error_code& ec, | ||
|  |         Iterator& iter, Iterator& end) | ||
|  |     { | ||
|  |       iter = detail::call_connect_condition(connect_condition_, ec, iter, end); | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     ConnectCondition connect_condition_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   // The default_connect_condition implementation is essentially a no-op. This
 | ||
|  |   // template specialisation lets us eliminate all costs associated with it.
 | ||
|  |   template <> | ||
|  |   class base_from_connect_condition<default_connect_condition> | ||
|  |   { | ||
|  |   protected: | ||
|  |     explicit base_from_connect_condition(const default_connect_condition&) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename Iterator> | ||
|  |     void check_condition(const asio::error_code&, Iterator&, Iterator&) | ||
|  |     { | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename EndpointSequence, | ||
|  |       typename ConnectCondition, typename RangeConnectHandler> | ||
|  |   class range_connect_op | ||
|  |     : public base_from_cancellation_state<RangeConnectHandler>, | ||
|  |       base_from_connect_condition<ConnectCondition> | ||
|  |   { | ||
|  |   public: | ||
|  |     range_connect_op(basic_socket<Protocol, Executor>& sock, | ||
|  |         const EndpointSequence& endpoints, | ||
|  |         const ConnectCondition& connect_condition, | ||
|  |         RangeConnectHandler& handler) | ||
|  |       : base_from_cancellation_state<RangeConnectHandler>( | ||
|  |           handler, enable_partial_cancellation()), | ||
|  |         base_from_connect_condition<ConnectCondition>(connect_condition), | ||
|  |         socket_(sock), | ||
|  |         endpoints_(endpoints), | ||
|  |         index_(0), | ||
|  |         start_(0), | ||
|  |         handler_(ASIO_MOVE_CAST(RangeConnectHandler)(handler)) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_MOVE)
 | ||
|  |     range_connect_op(const range_connect_op& other) | ||
|  |       : base_from_cancellation_state<RangeConnectHandler>(other), | ||
|  |         base_from_connect_condition<ConnectCondition>(other), | ||
|  |         socket_(other.socket_), | ||
|  |         endpoints_(other.endpoints_), | ||
|  |         index_(other.index_), | ||
|  |         start_(other.start_), | ||
|  |         handler_(other.handler_) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     range_connect_op(range_connect_op&& other) | ||
|  |       : base_from_cancellation_state<RangeConnectHandler>( | ||
|  |           ASIO_MOVE_CAST(base_from_cancellation_state< | ||
|  |             RangeConnectHandler>)(other)), | ||
|  |         base_from_connect_condition<ConnectCondition>(other), | ||
|  |         socket_(other.socket_), | ||
|  |         endpoints_(other.endpoints_), | ||
|  |         index_(other.index_), | ||
|  |         start_(other.start_), | ||
|  |         handler_(ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_)) | ||
|  |     { | ||
|  |     } | ||
|  | #endif // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |     void operator()(asio::error_code ec, int start = 0) | ||
|  |     { | ||
|  |       this->process(ec, start, | ||
|  |           const_cast<const EndpointSequence&>(endpoints_).begin(), | ||
|  |           const_cast<const EndpointSequence&>(endpoints_).end()); | ||
|  |     } | ||
|  | 
 | ||
|  |   //private:
 | ||
|  |     template <typename Iterator> | ||
|  |     void process(asio::error_code ec, | ||
|  |         int start, Iterator begin, Iterator end) | ||
|  |     { | ||
|  |       Iterator iter = begin; | ||
|  |       std::advance(iter, index_); | ||
|  | 
 | ||
|  |       switch (start_ = start) | ||
|  |       { | ||
|  |         case 1: | ||
|  |         for (;;) | ||
|  |         { | ||
|  |           this->check_condition(ec, iter, end); | ||
|  |           index_ = std::distance(begin, iter); | ||
|  | 
 | ||
|  |           if (iter != end) | ||
|  |           { | ||
|  |             socket_.close(ec); | ||
|  |             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); | ||
|  |             socket_.async_connect(*iter, | ||
|  |                 ASIO_MOVE_CAST(range_connect_op)(*this)); | ||
|  |             return; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (start) | ||
|  |           { | ||
|  |             ec = asio::error::not_found; | ||
|  |             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); | ||
|  |             asio::post(socket_.get_executor(), | ||
|  |                 detail::bind_handler( | ||
|  |                   ASIO_MOVE_CAST(range_connect_op)(*this), ec)); | ||
|  |             return; | ||
|  |           } | ||
|  | 
 | ||
|  |           /* fall-through */ default: | ||
|  | 
 | ||
|  |           if (iter == end) | ||
|  |             break; | ||
|  | 
 | ||
|  |           if (!socket_.is_open()) | ||
|  |           { | ||
|  |             ec = asio::error::operation_aborted; | ||
|  |             break; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (!ec) | ||
|  |             break; | ||
|  | 
 | ||
|  |           if (this->cancelled() != cancellation_type::none) | ||
|  |           { | ||
|  |             ec = asio::error::operation_aborted; | ||
|  |             break; | ||
|  |           } | ||
|  | 
 | ||
|  |           ++iter; | ||
|  |           ++index_; | ||
|  |         } | ||
|  | 
 | ||
|  |         ASIO_MOVE_OR_LVALUE(RangeConnectHandler)(handler_)( | ||
|  |             static_cast<const asio::error_code&>(ec), | ||
|  |             static_cast<const typename Protocol::endpoint&>( | ||
|  |               ec || iter == end ? typename Protocol::endpoint() : *iter)); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     basic_socket<Protocol, Executor>& socket_; | ||
|  |     EndpointSequence endpoints_; | ||
|  |     std::size_t index_; | ||
|  |     int start_; | ||
|  |     RangeConnectHandler handler_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename EndpointSequence, | ||
|  |       typename ConnectCondition, typename RangeConnectHandler> | ||
|  |   inline asio_handler_allocate_is_deprecated | ||
|  |   asio_handler_allocate(std::size_t size, | ||
|  |       range_connect_op<Protocol, Executor, EndpointSequence, | ||
|  |         ConnectCondition, RangeConnectHandler>* this_handler) | ||
|  |   { | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     asio_handler_alloc_helpers::allocate(size, this_handler->handler_); | ||
|  |     return asio_handler_allocate_is_no_longer_used(); | ||
|  | #else // defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_alloc_helpers::allocate( | ||
|  |         size, this_handler->handler_); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename EndpointSequence, | ||
|  |       typename ConnectCondition, typename RangeConnectHandler> | ||
|  |   inline asio_handler_deallocate_is_deprecated | ||
|  |   asio_handler_deallocate(void* pointer, std::size_t size, | ||
|  |       range_connect_op<Protocol, Executor, EndpointSequence, | ||
|  |         ConnectCondition, RangeConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     asio_handler_alloc_helpers::deallocate( | ||
|  |         pointer, size, this_handler->handler_); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_deallocate_is_no_longer_used(); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename EndpointSequence, | ||
|  |       typename ConnectCondition, typename RangeConnectHandler> | ||
|  |   inline bool asio_handler_is_continuation( | ||
|  |       range_connect_op<Protocol, Executor, EndpointSequence, | ||
|  |         ConnectCondition, RangeConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     return asio_handler_cont_helpers::is_continuation( | ||
|  |         this_handler->handler_); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Function, typename Executor, typename Protocol, | ||
|  |       typename EndpointSequence, typename ConnectCondition, | ||
|  |       typename RangeConnectHandler> | ||
|  |   inline asio_handler_invoke_is_deprecated | ||
|  |   asio_handler_invoke(Function& function, | ||
|  |       range_connect_op<Protocol, Executor, EndpointSequence, | ||
|  |         ConnectCondition, RangeConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     asio_handler_invoke_helpers::invoke( | ||
|  |         function, this_handler->handler_); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_invoke_is_no_longer_used(); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Function, typename Executor, typename Protocol, | ||
|  |       typename EndpointSequence, typename ConnectCondition, | ||
|  |       typename RangeConnectHandler> | ||
|  |   inline asio_handler_invoke_is_deprecated | ||
|  |   asio_handler_invoke(const Function& function, | ||
|  |       range_connect_op<Protocol, Executor, EndpointSequence, | ||
|  |         ConnectCondition, RangeConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     asio_handler_invoke_helpers::invoke( | ||
|  |         function, this_handler->handler_); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_invoke_is_no_longer_used(); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor> | ||
|  |   class initiate_async_range_connect | ||
|  |   { | ||
|  |   public: | ||
|  |     typedef Executor executor_type; | ||
|  | 
 | ||
|  |     explicit initiate_async_range_connect(basic_socket<Protocol, Executor>& s) | ||
|  |       : socket_(s) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     executor_type get_executor() const ASIO_NOEXCEPT | ||
|  |     { | ||
|  |       return socket_.get_executor(); | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename RangeConnectHandler, | ||
|  |         typename EndpointSequence, typename ConnectCondition> | ||
|  |     void operator()(ASIO_MOVE_ARG(RangeConnectHandler) handler, | ||
|  |         const EndpointSequence& endpoints, | ||
|  |         const ConnectCondition& connect_condition) const | ||
|  |     { | ||
|  |       // If you get an error on the following line it means that your
 | ||
|  |       // handler does not meet the documented type requirements for an
 | ||
|  |       // RangeConnectHandler.
 | ||
|  |       ASIO_RANGE_CONNECT_HANDLER_CHECK(RangeConnectHandler, | ||
|  |           handler, typename Protocol::endpoint) type_check; | ||
|  | 
 | ||
|  |       non_const_lvalue<RangeConnectHandler> handler2(handler); | ||
|  |       range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition, | ||
|  |         typename decay<RangeConnectHandler>::type>(socket_, endpoints, | ||
|  |           connect_condition, handler2.value)(asio::error_code(), 1); | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     basic_socket<Protocol, Executor>& socket_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename Iterator, | ||
|  |       typename ConnectCondition, typename IteratorConnectHandler> | ||
|  |   class iterator_connect_op | ||
|  |     : public base_from_cancellation_state<IteratorConnectHandler>, | ||
|  |       base_from_connect_condition<ConnectCondition> | ||
|  |   { | ||
|  |   public: | ||
|  |     iterator_connect_op(basic_socket<Protocol, Executor>& sock, | ||
|  |         const Iterator& begin, const Iterator& end, | ||
|  |         const ConnectCondition& connect_condition, | ||
|  |         IteratorConnectHandler& handler) | ||
|  |       : base_from_cancellation_state<IteratorConnectHandler>( | ||
|  |           handler, enable_partial_cancellation()), | ||
|  |         base_from_connect_condition<ConnectCondition>(connect_condition), | ||
|  |         socket_(sock), | ||
|  |         iter_(begin), | ||
|  |         end_(end), | ||
|  |         start_(0), | ||
|  |         handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(handler)) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  | #if defined(ASIO_HAS_MOVE)
 | ||
|  |     iterator_connect_op(const iterator_connect_op& other) | ||
|  |       : base_from_cancellation_state<IteratorConnectHandler>(other), | ||
|  |         base_from_connect_condition<ConnectCondition>(other), | ||
|  |         socket_(other.socket_), | ||
|  |         iter_(other.iter_), | ||
|  |         end_(other.end_), | ||
|  |         start_(other.start_), | ||
|  |         handler_(other.handler_) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     iterator_connect_op(iterator_connect_op&& other) | ||
|  |       : base_from_cancellation_state<IteratorConnectHandler>( | ||
|  |           ASIO_MOVE_CAST(base_from_cancellation_state< | ||
|  |             IteratorConnectHandler>)(other)), | ||
|  |         base_from_connect_condition<ConnectCondition>(other), | ||
|  |         socket_(other.socket_), | ||
|  |         iter_(other.iter_), | ||
|  |         end_(other.end_), | ||
|  |         start_(other.start_), | ||
|  |         handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_)) | ||
|  |     { | ||
|  |     } | ||
|  | #endif // defined(ASIO_HAS_MOVE)
 | ||
|  | 
 | ||
|  |     void operator()(asio::error_code ec, int start = 0) | ||
|  |     { | ||
|  |       switch (start_ = start) | ||
|  |       { | ||
|  |         case 1: | ||
|  |         for (;;) | ||
|  |         { | ||
|  |           this->check_condition(ec, iter_, end_); | ||
|  | 
 | ||
|  |           if (iter_ != end_) | ||
|  |           { | ||
|  |             socket_.close(ec); | ||
|  |             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); | ||
|  |             socket_.async_connect(*iter_, | ||
|  |                 ASIO_MOVE_CAST(iterator_connect_op)(*this)); | ||
|  |             return; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (start) | ||
|  |           { | ||
|  |             ec = asio::error::not_found; | ||
|  |             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); | ||
|  |             asio::post(socket_.get_executor(), | ||
|  |                 detail::bind_handler( | ||
|  |                   ASIO_MOVE_CAST(iterator_connect_op)(*this), ec)); | ||
|  |             return; | ||
|  |           } | ||
|  | 
 | ||
|  |           /* fall-through */ default: | ||
|  | 
 | ||
|  |           if (iter_ == end_) | ||
|  |             break; | ||
|  | 
 | ||
|  |           if (!socket_.is_open()) | ||
|  |           { | ||
|  |             ec = asio::error::operation_aborted; | ||
|  |             break; | ||
|  |           } | ||
|  | 
 | ||
|  |           if (!ec) | ||
|  |             break; | ||
|  | 
 | ||
|  |           if (this->cancelled() != cancellation_type::none) | ||
|  |           { | ||
|  |             ec = asio::error::operation_aborted; | ||
|  |             break; | ||
|  |           } | ||
|  | 
 | ||
|  |           ++iter_; | ||
|  |         } | ||
|  | 
 | ||
|  |         ASIO_MOVE_OR_LVALUE(IteratorConnectHandler)(handler_)( | ||
|  |             static_cast<const asio::error_code&>(ec), | ||
|  |             static_cast<const Iterator&>(iter_)); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |   //private:
 | ||
|  |     basic_socket<Protocol, Executor>& socket_; | ||
|  |     Iterator iter_; | ||
|  |     Iterator end_; | ||
|  |     int start_; | ||
|  |     IteratorConnectHandler handler_; | ||
|  |   }; | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename Iterator, | ||
|  |       typename ConnectCondition, typename IteratorConnectHandler> | ||
|  |   inline asio_handler_allocate_is_deprecated | ||
|  |   asio_handler_allocate(std::size_t size, | ||
|  |       iterator_connect_op<Protocol, Executor, Iterator, | ||
|  |         ConnectCondition, IteratorConnectHandler>* this_handler) | ||
|  |   { | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     asio_handler_alloc_helpers::allocate(size, this_handler->handler_); | ||
|  |     return asio_handler_allocate_is_no_longer_used(); | ||
|  | #else // defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_alloc_helpers::allocate( | ||
|  |         size, this_handler->handler_); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename Iterator, | ||
|  |       typename ConnectCondition, typename IteratorConnectHandler> | ||
|  |   inline asio_handler_deallocate_is_deprecated | ||
|  |   asio_handler_deallocate(void* pointer, std::size_t size, | ||
|  |       iterator_connect_op<Protocol, Executor, Iterator, | ||
|  |         ConnectCondition, IteratorConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     asio_handler_alloc_helpers::deallocate( | ||
|  |         pointer, size, this_handler->handler_); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_deallocate_is_no_longer_used(); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor, typename Iterator, | ||
|  |       typename ConnectCondition, typename IteratorConnectHandler> | ||
|  |   inline bool asio_handler_is_continuation( | ||
|  |       iterator_connect_op<Protocol, Executor, Iterator, | ||
|  |         ConnectCondition, IteratorConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     return asio_handler_cont_helpers::is_continuation( | ||
|  |         this_handler->handler_); | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Function, typename Executor, typename Protocol, | ||
|  |       typename Iterator, typename ConnectCondition, | ||
|  |       typename IteratorConnectHandler> | ||
|  |   inline asio_handler_invoke_is_deprecated | ||
|  |   asio_handler_invoke(Function& function, | ||
|  |       iterator_connect_op<Protocol, Executor, Iterator, | ||
|  |         ConnectCondition, IteratorConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     asio_handler_invoke_helpers::invoke( | ||
|  |         function, this_handler->handler_); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_invoke_is_no_longer_used(); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Function, typename Executor, typename Protocol, | ||
|  |       typename Iterator, typename ConnectCondition, | ||
|  |       typename IteratorConnectHandler> | ||
|  |   inline asio_handler_invoke_is_deprecated | ||
|  |   asio_handler_invoke(const Function& function, | ||
|  |       iterator_connect_op<Protocol, Executor, Iterator, | ||
|  |         ConnectCondition, IteratorConnectHandler>* this_handler) | ||
|  |   { | ||
|  |     asio_handler_invoke_helpers::invoke( | ||
|  |         function, this_handler->handler_); | ||
|  | #if defined(ASIO_NO_DEPRECATED)
 | ||
|  |     return asio_handler_invoke_is_no_longer_used(); | ||
|  | #endif // defined(ASIO_NO_DEPRECATED)
 | ||
|  |   } | ||
|  | 
 | ||
|  |   template <typename Protocol, typename Executor> | ||
|  |   class initiate_async_iterator_connect | ||
|  |   { | ||
|  |   public: | ||
|  |     typedef Executor executor_type; | ||
|  | 
 | ||
|  |     explicit initiate_async_iterator_connect( | ||
|  |         basic_socket<Protocol, Executor>& s) | ||
|  |       : socket_(s) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     executor_type get_executor() const ASIO_NOEXCEPT | ||
|  |     { | ||
|  |       return socket_.get_executor(); | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename IteratorConnectHandler, | ||
|  |         typename Iterator, typename ConnectCondition> | ||
|  |     void operator()(ASIO_MOVE_ARG(IteratorConnectHandler) handler, | ||
|  |         Iterator begin, Iterator end, | ||
|  |         const ConnectCondition& connect_condition) const | ||
|  |     { | ||
|  |       // If you get an error on the following line it means that your
 | ||
|  |       // handler does not meet the documented type requirements for an
 | ||
|  |       // IteratorConnectHandler.
 | ||
|  |       ASIO_ITERATOR_CONNECT_HANDLER_CHECK( | ||
|  |           IteratorConnectHandler, handler, Iterator) type_check; | ||
|  | 
 | ||
|  |       non_const_lvalue<IteratorConnectHandler> handler2(handler); | ||
|  |       iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition, | ||
|  |         typename decay<IteratorConnectHandler>::type>(socket_, begin, end, | ||
|  |           connect_condition, handler2.value)(asio::error_code(), 1); | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     basic_socket<Protocol, Executor>& socket_; | ||
|  |   }; | ||
|  | } // namespace detail
 | ||
|  | 
 | ||
|  | #if !defined(GENERATING_DOCUMENTATION)
 | ||
|  | 
 | ||
|  | template <template <typename, typename> class Associator, | ||
|  |     typename Protocol, typename Executor, typename EndpointSequence, | ||
|  |     typename ConnectCondition, typename RangeConnectHandler, | ||
|  |     typename DefaultCandidate> | ||
|  | struct associator<Associator, | ||
|  |     detail::range_connect_op<Protocol, Executor, | ||
|  |       EndpointSequence, ConnectCondition, RangeConnectHandler>, | ||
|  |     DefaultCandidate> | ||
|  |   : Associator<RangeConnectHandler, DefaultCandidate> | ||
|  | { | ||
|  |   static typename Associator<RangeConnectHandler, DefaultCandidate>::type | ||
|  |   get(const detail::range_connect_op<Protocol, Executor, EndpointSequence, | ||
|  |         ConnectCondition, RangeConnectHandler>& h) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return Associator<RangeConnectHandler, DefaultCandidate>::get(h.handler_); | ||
|  |   } | ||
|  | 
 | ||
|  |   static ASIO_AUTO_RETURN_TYPE_PREFIX2( | ||
|  |       typename Associator<RangeConnectHandler, DefaultCandidate>::type) | ||
|  |   get(const detail::range_connect_op<Protocol, Executor, | ||
|  |         EndpointSequence, ConnectCondition, RangeConnectHandler>& h, | ||
|  |       const DefaultCandidate& c) ASIO_NOEXCEPT | ||
|  |     ASIO_AUTO_RETURN_TYPE_SUFFIX(( | ||
|  |       Associator<RangeConnectHandler, DefaultCandidate>::get( | ||
|  |         h.handler_, c))) | ||
|  |   { | ||
|  |     return Associator<RangeConnectHandler, DefaultCandidate>::get( | ||
|  |         h.handler_, c); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | template <template <typename, typename> class Associator, | ||
|  |     typename Protocol, typename Executor, typename Iterator, | ||
|  |     typename ConnectCondition, typename IteratorConnectHandler, | ||
|  |     typename DefaultCandidate> | ||
|  | struct associator<Associator, | ||
|  |     detail::iterator_connect_op<Protocol, Executor, | ||
|  |       Iterator, ConnectCondition, IteratorConnectHandler>, | ||
|  |     DefaultCandidate> | ||
|  |   : Associator<IteratorConnectHandler, DefaultCandidate> | ||
|  | { | ||
|  |   static typename Associator<IteratorConnectHandler, DefaultCandidate>::type | ||
|  |   get(const detail::iterator_connect_op<Protocol, Executor, Iterator, | ||
|  |         ConnectCondition, IteratorConnectHandler>& h) ASIO_NOEXCEPT | ||
|  |   { | ||
|  |     return Associator<IteratorConnectHandler, DefaultCandidate>::get( | ||
|  |         h.handler_); | ||
|  |   } | ||
|  | 
 | ||
|  |   static ASIO_AUTO_RETURN_TYPE_PREFIX2( | ||
|  |       typename Associator<IteratorConnectHandler, DefaultCandidate>::type) | ||
|  |   get(const detail::iterator_connect_op<Protocol, Executor, | ||
|  |         Iterator, ConnectCondition, IteratorConnectHandler>& h, | ||
|  |       const DefaultCandidate& c) ASIO_NOEXCEPT | ||
|  |     ASIO_AUTO_RETURN_TYPE_SUFFIX(( | ||
|  |       Associator<IteratorConnectHandler, DefaultCandidate>::get( | ||
|  |         h.handler_, c))) | ||
|  |   { | ||
|  |     return Associator<IteratorConnectHandler, DefaultCandidate>::get( | ||
|  |         h.handler_, c); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | #endif // !defined(GENERATING_DOCUMENTATION)
 | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, typename EndpointSequence, | ||
|  |     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, | ||
|  |       typename Protocol::endpoint)) RangeConnectToken> | ||
|  | inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken, | ||
|  |     void (asio::error_code, typename Protocol::endpoint)) | ||
|  | async_connect(basic_socket<Protocol, Executor>& s, | ||
|  |     const EndpointSequence& endpoints, | ||
|  |     ASIO_MOVE_ARG(RangeConnectToken) token, | ||
|  |     typename constraint<is_endpoint_sequence< | ||
|  |         EndpointSequence>::value>::type) | ||
|  |   ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( | ||
|  |     async_initiate<RangeConnectToken, | ||
|  |       void (asio::error_code, typename Protocol::endpoint)>( | ||
|  |         declval<detail::initiate_async_range_connect<Protocol, Executor> >(), | ||
|  |         token, endpoints, declval<detail::default_connect_condition>()))) | ||
|  | { | ||
|  |   return async_initiate<RangeConnectToken, | ||
|  |     void (asio::error_code, typename Protocol::endpoint)>( | ||
|  |       detail::initiate_async_range_connect<Protocol, Executor>(s), | ||
|  |       token, endpoints, detail::default_connect_condition()); | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_DEPRECATED)
 | ||
|  | template <typename Protocol, typename Executor, typename Iterator, | ||
|  |     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, | ||
|  |       Iterator)) IteratorConnectToken> | ||
|  | inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)) | ||
|  | async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, | ||
|  |     ASIO_MOVE_ARG(IteratorConnectToken) token, | ||
|  |     typename constraint<!is_endpoint_sequence<Iterator>::value>::type) | ||
|  |   ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( | ||
|  |     async_initiate<IteratorConnectToken, | ||
|  |       void (asio::error_code, Iterator)>( | ||
|  |         declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(), | ||
|  |         token, begin, Iterator(), | ||
|  |         declval<detail::default_connect_condition>()))) | ||
|  | { | ||
|  |   return async_initiate<IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)>( | ||
|  |       detail::initiate_async_iterator_connect<Protocol, Executor>(s), | ||
|  |       token, begin, Iterator(), | ||
|  |       detail::default_connect_condition()); | ||
|  | } | ||
|  | #endif // !defined(ASIO_NO_DEPRECATED)
 | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, typename Iterator, | ||
|  |     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, | ||
|  |       Iterator)) IteratorConnectToken> | ||
|  | inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)) | ||
|  | async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end, | ||
|  |     ASIO_MOVE_ARG(IteratorConnectToken) token) | ||
|  |   ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( | ||
|  |     async_initiate<IteratorConnectToken, | ||
|  |       void (asio::error_code, Iterator)>( | ||
|  |         declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(), | ||
|  |         token, begin, end, declval<detail::default_connect_condition>()))) | ||
|  | { | ||
|  |   return async_initiate<IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)>( | ||
|  |       detail::initiate_async_iterator_connect<Protocol, Executor>(s), | ||
|  |       token, begin, end, detail::default_connect_condition()); | ||
|  | } | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename EndpointSequence, typename ConnectCondition, | ||
|  |     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, | ||
|  |       typename Protocol::endpoint)) RangeConnectToken> | ||
|  | inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken, | ||
|  |     void (asio::error_code, typename Protocol::endpoint)) | ||
|  | async_connect(basic_socket<Protocol, Executor>& s, | ||
|  |     const EndpointSequence& endpoints, ConnectCondition connect_condition, | ||
|  |     ASIO_MOVE_ARG(RangeConnectToken) token, | ||
|  |     typename constraint<is_endpoint_sequence< | ||
|  |         EndpointSequence>::value>::type) | ||
|  |   ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( | ||
|  |     async_initiate<RangeConnectToken, | ||
|  |       void (asio::error_code, typename Protocol::endpoint)>( | ||
|  |         declval<detail::initiate_async_range_connect<Protocol, Executor> >(), | ||
|  |         token, endpoints, connect_condition))) | ||
|  | { | ||
|  |   return async_initiate<RangeConnectToken, | ||
|  |     void (asio::error_code, typename Protocol::endpoint)>( | ||
|  |       detail::initiate_async_range_connect<Protocol, Executor>(s), | ||
|  |       token, endpoints, connect_condition); | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined(ASIO_NO_DEPRECATED)
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename Iterator, typename ConnectCondition, | ||
|  |     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, | ||
|  |       Iterator)) IteratorConnectToken> | ||
|  | inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)) | ||
|  | async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, | ||
|  |     ConnectCondition connect_condition, | ||
|  |     ASIO_MOVE_ARG(IteratorConnectToken) token, | ||
|  |     typename constraint<!is_endpoint_sequence<Iterator>::value>::type) | ||
|  |   ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( | ||
|  |     async_initiate<IteratorConnectToken, | ||
|  |       void (asio::error_code, Iterator)>( | ||
|  |         declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(), | ||
|  |         token, begin, Iterator(), connect_condition))) | ||
|  | { | ||
|  |   return async_initiate<IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)>( | ||
|  |       detail::initiate_async_iterator_connect<Protocol, Executor>(s), | ||
|  |       token, begin, Iterator(), connect_condition); | ||
|  | } | ||
|  | #endif // !defined(ASIO_NO_DEPRECATED)
 | ||
|  | 
 | ||
|  | template <typename Protocol, typename Executor, | ||
|  |     typename Iterator, typename ConnectCondition, | ||
|  |     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, | ||
|  |       Iterator)) IteratorConnectToken> | ||
|  | inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)) | ||
|  | async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, | ||
|  |     Iterator end, ConnectCondition connect_condition, | ||
|  |     ASIO_MOVE_ARG(IteratorConnectToken) token) | ||
|  |   ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( | ||
|  |     async_initiate<IteratorConnectToken, | ||
|  |       void (asio::error_code, Iterator)>( | ||
|  |         declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(), | ||
|  |         token, begin, end, connect_condition))) | ||
|  | { | ||
|  |   return async_initiate<IteratorConnectToken, | ||
|  |     void (asio::error_code, Iterator)>( | ||
|  |       detail::initiate_async_iterator_connect<Protocol, Executor>(s), | ||
|  |       token, begin, end, connect_condition); | ||
|  | } | ||
|  | 
 | ||
|  | } // namespace asio
 | ||
|  | 
 | ||
|  | #include "asio/detail/pop_options.hpp"
 | ||
|  | 
 | ||
|  | #endif // ASIO_IMPL_CONNECT_HPP
 |