5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_ASIO_IMPL_CONNECT_HPP
12 #define BOOST_ASIO_IMPL_CONNECT_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/asio/associated_allocator.hpp>
20 #include <boost/asio/associated_executor.hpp>
21 #include <boost/asio/detail/bind_handler.hpp>
22 #include <boost/asio/detail/handler_alloc_helpers.hpp>
23 #include <boost/asio/detail/handler_cont_helpers.hpp>
24 #include <boost/asio/detail/handler_invoke_helpers.hpp>
25 #include <boost/asio/detail/handler_type_requirements.hpp>
26 #include <boost/asio/detail/throw_error.hpp>
27 #include <boost/asio/error.hpp>
28 #include <boost/asio/post.hpp>
30 #include <boost/asio/detail/push_options.hpp>
37 struct default_connect_condition
39 template <typename Endpoint>
40 bool operator()(const boost::system::error_code&, const Endpoint&)
46 template <typename Protocol, typename Iterator>
47 inline typename Protocol::endpoint deref_connect_result(
48 Iterator iter, boost::system::error_code& ec)
50 return ec ? typename Protocol::endpoint() : *iter;
53 template <typename T, typename Iterator>
54 struct legacy_connect_condition_helper : T
56 typedef char (*fallback_func_type)(...);
57 operator fallback_func_type() const;
60 template <typename R, typename Arg1, typename Arg2, typename Iterator>
61 struct legacy_connect_condition_helper<R (*)(Arg1, Arg2), Iterator>
63 R operator()(Arg1, Arg2) const;
64 char operator()(...) const;
67 template <typename T, typename Iterator>
68 struct is_legacy_connect_condition
70 static char asio_connect_condition_check(char);
71 static char (&asio_connect_condition_check(Iterator))[2];
73 static const bool value =
74 sizeof(asio_connect_condition_check(
75 (*static_cast<legacy_connect_condition_helper<T, Iterator>*>(0))(
76 *static_cast<const boost::system::error_code*>(0),
77 *static_cast<const Iterator*>(0)))) != 1;
80 template <typename ConnectCondition, typename Iterator>
81 inline Iterator call_connect_condition(ConnectCondition& connect_condition,
82 const boost::system::error_code& ec, Iterator next, Iterator end,
83 typename enable_if<is_legacy_connect_condition<
84 ConnectCondition, Iterator>::value>::type* = 0)
87 return connect_condition(ec, next);
91 template <typename ConnectCondition, typename Iterator>
92 inline Iterator call_connect_condition(ConnectCondition& connect_condition,
93 const boost::system::error_code& ec, Iterator next, Iterator end,
94 typename enable_if<!is_legacy_connect_condition<
95 ConnectCondition, Iterator>::value>::type* = 0)
97 for (;next != end; ++next)
98 if (connect_condition(ec, *next))
104 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
105 typename Protocol::endpoint connect(
106 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
107 const EndpointSequence& endpoints,
108 typename enable_if<is_endpoint_sequence<
109 EndpointSequence>::value>::type*)
111 boost::system::error_code ec;
112 typename Protocol::endpoint result = connect(s, endpoints, ec);
113 boost::asio::detail::throw_error(ec, "connect");
117 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
118 typename Protocol::endpoint connect(
119 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
120 const EndpointSequence& endpoints, boost::system::error_code& ec,
121 typename enable_if<is_endpoint_sequence<
122 EndpointSequence>::value>::type*)
124 return detail::deref_connect_result<Protocol>(
125 connect(s, endpoints.begin(), endpoints.end(),
126 detail::default_connect_condition(), ec), ec);
129 #if !defined(BOOST_ASIO_NO_DEPRECATED)
130 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
131 Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
132 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
134 boost::system::error_code ec;
135 Iterator result = connect(s, begin, ec);
136 boost::asio::detail::throw_error(ec, "connect");
140 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
141 inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
142 Iterator begin, boost::system::error_code& ec,
143 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
145 return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);
147 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
149 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
150 Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
151 Iterator begin, Iterator end)
153 boost::system::error_code ec;
154 Iterator result = connect(s, begin, end, ec);
155 boost::asio::detail::throw_error(ec, "connect");
159 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
160 inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
161 Iterator begin, Iterator end, boost::system::error_code& ec)
163 return connect(s, begin, end, detail::default_connect_condition(), ec);
166 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
167 typename EndpointSequence, typename ConnectCondition>
168 typename Protocol::endpoint connect(
169 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
170 const EndpointSequence& endpoints, ConnectCondition connect_condition,
171 typename enable_if<is_endpoint_sequence<
172 EndpointSequence>::value>::type*)
174 boost::system::error_code ec;
175 typename Protocol::endpoint result = connect(
176 s, endpoints, connect_condition, ec);
177 boost::asio::detail::throw_error(ec, "connect");
181 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
182 typename EndpointSequence, typename ConnectCondition>
183 typename Protocol::endpoint connect(
184 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
185 const EndpointSequence& endpoints, ConnectCondition connect_condition,
186 boost::system::error_code& ec,
187 typename enable_if<is_endpoint_sequence<
188 EndpointSequence>::value>::type*)
190 return detail::deref_connect_result<Protocol>(
191 connect(s, endpoints.begin(), endpoints.end(),
192 connect_condition, ec), ec);
195 #if !defined(BOOST_ASIO_NO_DEPRECATED)
196 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
197 typename Iterator, typename ConnectCondition>
198 Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
199 Iterator begin, ConnectCondition connect_condition,
200 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
202 boost::system::error_code ec;
203 Iterator result = connect(s, begin, connect_condition, ec);
204 boost::asio::detail::throw_error(ec, "connect");
208 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
209 typename Iterator, typename ConnectCondition>
210 inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
211 Iterator begin, ConnectCondition connect_condition,
212 boost::system::error_code& ec,
213 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
215 return connect(s, begin, Iterator(), connect_condition, ec);
217 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
219 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
220 typename Iterator, typename ConnectCondition>
221 Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
222 Iterator begin, Iterator end, ConnectCondition connect_condition)
224 boost::system::error_code ec;
225 Iterator result = connect(s, begin, end, connect_condition, ec);
226 boost::asio::detail::throw_error(ec, "connect");
230 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
231 typename Iterator, typename ConnectCondition>
232 Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
233 Iterator begin, Iterator end, ConnectCondition connect_condition,
234 boost::system::error_code& ec)
236 ec = boost::system::error_code();
238 for (Iterator iter = begin; iter != end; ++iter)
240 iter = (detail::call_connect_condition(connect_condition, ec, iter, end));
244 s.connect(*iter, ec);
253 ec = boost::asio::error::not_found;
260 // Enable the empty base class optimisation for the connect condition.
261 template <typename ConnectCondition>
262 class base_from_connect_condition
265 explicit base_from_connect_condition(
266 const ConnectCondition& connect_condition)
267 : connect_condition_(connect_condition)
271 template <typename Iterator>
272 void check_condition(const boost::system::error_code& ec,
273 Iterator& iter, Iterator& end)
275 iter = detail::call_connect_condition(connect_condition_, ec, iter, end);
279 ConnectCondition connect_condition_;
282 // The default_connect_condition implementation is essentially a no-op. This
283 // template specialisation lets us eliminate all costs associated with it.
285 class base_from_connect_condition<default_connect_condition>
288 explicit base_from_connect_condition(const default_connect_condition&)
292 template <typename Iterator>
293 void check_condition(const boost::system::error_code&, Iterator&, Iterator&)
298 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
299 typename EndpointSequence, typename ConnectCondition,
300 typename RangeConnectHandler>
301 class range_connect_op : base_from_connect_condition<ConnectCondition>
304 range_connect_op(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& sock,
305 const EndpointSequence& endpoints,
306 const ConnectCondition& connect_condition,
307 RangeConnectHandler& handler)
308 : base_from_connect_condition<ConnectCondition>(connect_condition),
310 endpoints_(endpoints),
313 handler_(BOOST_ASIO_MOVE_CAST(RangeConnectHandler)(handler))
317 #if defined(BOOST_ASIO_HAS_MOVE)
318 range_connect_op(const range_connect_op& other)
319 : base_from_connect_condition<ConnectCondition>(other),
320 socket_(other.socket_),
321 endpoints_(other.endpoints_),
322 index_(other.index_),
323 start_(other.start_),
324 handler_(other.handler_)
328 range_connect_op(range_connect_op&& other)
329 : base_from_connect_condition<ConnectCondition>(other),
330 socket_(other.socket_),
331 endpoints_(other.endpoints_),
332 index_(other.index_),
333 start_(other.start_),
334 handler_(BOOST_ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_))
337 #endif // defined(BOOST_ASIO_HAS_MOVE)
339 void operator()(boost::system::error_code ec, int start = 0)
341 typename EndpointSequence::const_iterator begin = endpoints_.begin();
342 typename EndpointSequence::const_iterator iter = begin;
343 std::advance(iter, index_);
344 typename EndpointSequence::const_iterator end = endpoints_.end();
346 switch (start_ = start)
351 this->check_condition(ec, iter, end);
352 index_ = std::distance(begin, iter);
357 socket_.async_connect(*iter,
358 BOOST_ASIO_MOVE_CAST(range_connect_op)(*this));
364 ec = boost::asio::error::not_found;
365 boost::asio::post(socket_.get_executor(),
366 detail::bind_handler(
367 BOOST_ASIO_MOVE_CAST(range_connect_op)(*this), ec));
376 if (!socket_.is_open())
378 ec = boost::asio::error::operation_aborted;
389 handler_(static_cast<const boost::system::error_code&>(ec),
390 static_cast<const typename Protocol::endpoint&>(
391 ec || iter == end ? typename Protocol::endpoint() : *iter));
396 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket_;
397 EndpointSequence endpoints_;
400 RangeConnectHandler handler_;
403 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
404 typename EndpointSequence, typename ConnectCondition,
405 typename RangeConnectHandler>
406 inline void* asio_handler_allocate(std::size_t size,
407 range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
408 ConnectCondition, RangeConnectHandler>* this_handler)
410 return boost_asio_handler_alloc_helpers::allocate(
411 size, this_handler->handler_);
414 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
415 typename EndpointSequence, typename ConnectCondition,
416 typename RangeConnectHandler>
417 inline void asio_handler_deallocate(void* pointer, std::size_t size,
418 range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
419 ConnectCondition, RangeConnectHandler>* this_handler)
421 boost_asio_handler_alloc_helpers::deallocate(
422 pointer, size, this_handler->handler_);
425 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
426 typename EndpointSequence, typename ConnectCondition,
427 typename RangeConnectHandler>
428 inline bool asio_handler_is_continuation(
429 range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
430 ConnectCondition, RangeConnectHandler>* this_handler)
432 return boost_asio_handler_cont_helpers::is_continuation(
433 this_handler->handler_);
436 template <typename Function, typename Protocol
437 BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
438 typename ConnectCondition, typename RangeConnectHandler>
439 inline void asio_handler_invoke(Function& function,
440 range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
441 ConnectCondition, RangeConnectHandler>* this_handler)
443 boost_asio_handler_invoke_helpers::invoke(
444 function, this_handler->handler_);
447 template <typename Function, typename Protocol
448 BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
449 typename ConnectCondition, typename RangeConnectHandler>
450 inline void asio_handler_invoke(const Function& function,
451 range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
452 ConnectCondition, RangeConnectHandler>* this_handler)
454 boost_asio_handler_invoke_helpers::invoke(
455 function, this_handler->handler_);
458 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
459 typename ConnectCondition, typename IteratorConnectHandler>
460 class iterator_connect_op : base_from_connect_condition<ConnectCondition>
463 iterator_connect_op(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& sock,
464 const Iterator& begin, const Iterator& end,
465 const ConnectCondition& connect_condition,
466 IteratorConnectHandler& handler)
467 : base_from_connect_condition<ConnectCondition>(connect_condition),
472 handler_(BOOST_ASIO_MOVE_CAST(IteratorConnectHandler)(handler))
476 #if defined(BOOST_ASIO_HAS_MOVE)
477 iterator_connect_op(const iterator_connect_op& other)
478 : base_from_connect_condition<ConnectCondition>(other),
479 socket_(other.socket_),
482 start_(other.start_),
483 handler_(other.handler_)
487 iterator_connect_op(iterator_connect_op&& other)
488 : base_from_connect_condition<ConnectCondition>(other),
489 socket_(other.socket_),
492 start_(other.start_),
493 handler_(BOOST_ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_))
496 #endif // defined(BOOST_ASIO_HAS_MOVE)
498 void operator()(boost::system::error_code ec, int start = 0)
500 switch (start_ = start)
505 this->check_condition(ec, iter_, end_);
510 socket_.async_connect(*iter_,
511 BOOST_ASIO_MOVE_CAST(iterator_connect_op)(*this));
517 ec = boost::asio::error::not_found;
518 boost::asio::post(socket_.get_executor(),
519 detail::bind_handler(
520 BOOST_ASIO_MOVE_CAST(iterator_connect_op)(*this), ec));
529 if (!socket_.is_open())
531 ec = boost::asio::error::operation_aborted;
541 handler_(static_cast<const boost::system::error_code&>(ec),
542 static_cast<const Iterator&>(iter_));
547 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket_;
551 IteratorConnectHandler handler_;
554 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
555 typename ConnectCondition, typename IteratorConnectHandler>
556 inline void* asio_handler_allocate(std::size_t size,
557 iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
558 ConnectCondition, IteratorConnectHandler>* this_handler)
560 return boost_asio_handler_alloc_helpers::allocate(
561 size, this_handler->handler_);
564 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
565 typename ConnectCondition, typename IteratorConnectHandler>
566 inline void asio_handler_deallocate(void* pointer, std::size_t size,
567 iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
568 ConnectCondition, IteratorConnectHandler>* this_handler)
570 boost_asio_handler_alloc_helpers::deallocate(
571 pointer, size, this_handler->handler_);
574 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
575 typename ConnectCondition, typename IteratorConnectHandler>
576 inline bool asio_handler_is_continuation(
577 iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
578 ConnectCondition, IteratorConnectHandler>* this_handler)
580 return boost_asio_handler_cont_helpers::is_continuation(
581 this_handler->handler_);
584 template <typename Function, typename Protocol
585 BOOST_ASIO_SVC_TPARAM, typename Iterator,
586 typename ConnectCondition, typename IteratorConnectHandler>
587 inline void asio_handler_invoke(Function& function,
588 iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
589 ConnectCondition, IteratorConnectHandler>* this_handler)
591 boost_asio_handler_invoke_helpers::invoke(
592 function, this_handler->handler_);
595 template <typename Function, typename Protocol
596 BOOST_ASIO_SVC_TPARAM, typename Iterator,
597 typename ConnectCondition, typename IteratorConnectHandler>
598 inline void asio_handler_invoke(const Function& function,
599 iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
600 ConnectCondition, IteratorConnectHandler>* this_handler)
602 boost_asio_handler_invoke_helpers::invoke(
603 function, this_handler->handler_);
605 } // namespace detail
607 #if !defined(GENERATING_DOCUMENTATION)
609 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
610 typename EndpointSequence, typename ConnectCondition,
611 typename RangeConnectHandler, typename Allocator>
612 struct associated_allocator<
613 detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
614 EndpointSequence, ConnectCondition, RangeConnectHandler>,
617 typedef typename associated_allocator<
618 RangeConnectHandler, Allocator>::type type;
621 const detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
622 EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
623 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
625 return associated_allocator<RangeConnectHandler,
626 Allocator>::get(h.handler_, a);
630 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
631 typename EndpointSequence, typename ConnectCondition,
632 typename RangeConnectHandler, typename Executor>
633 struct associated_executor<
634 detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
635 EndpointSequence, ConnectCondition, RangeConnectHandler>,
638 typedef typename associated_executor<
639 RangeConnectHandler, Executor>::type type;
642 const detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
643 EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
644 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
646 return associated_executor<RangeConnectHandler,
647 Executor>::get(h.handler_, ex);
651 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
652 typename Iterator, typename ConnectCondition,
653 typename IteratorConnectHandler, typename Allocator>
654 struct associated_allocator<
655 detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
656 ConnectCondition, IteratorConnectHandler>,
659 typedef typename associated_allocator<
660 IteratorConnectHandler, Allocator>::type type;
663 const detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG,
664 Iterator, ConnectCondition, IteratorConnectHandler>& h,
665 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
667 return associated_allocator<IteratorConnectHandler,
668 Allocator>::get(h.handler_, a);
672 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
673 typename Iterator, typename ConnectCondition,
674 typename IteratorConnectHandler, typename Executor>
675 struct associated_executor<
676 detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
677 ConnectCondition, IteratorConnectHandler>,
680 typedef typename associated_executor<
681 IteratorConnectHandler, Executor>::type type;
684 const detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG,
685 Iterator, ConnectCondition, IteratorConnectHandler>& h,
686 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
688 return associated_executor<IteratorConnectHandler,
689 Executor>::get(h.handler_, ex);
693 #endif // !defined(GENERATING_DOCUMENTATION)
695 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
696 typename EndpointSequence, typename RangeConnectHandler>
697 inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
698 void (boost::system::error_code, typename Protocol::endpoint))
699 async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
700 const EndpointSequence& endpoints,
701 BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
702 typename enable_if<is_endpoint_sequence<
703 EndpointSequence>::value>::type*)
705 // If you get an error on the following line it means that your handler does
706 // not meet the documented type requirements for a RangeConnectHandler.
707 BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK(
708 RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
710 async_completion<RangeConnectHandler,
711 void (boost::system::error_code, typename Protocol::endpoint)>
714 detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
715 detail::default_connect_condition,
716 BOOST_ASIO_HANDLER_TYPE(RangeConnectHandler,
717 void (boost::system::error_code, typename Protocol::endpoint))>(s,
718 endpoints, detail::default_connect_condition(),
719 init.completion_handler)(boost::system::error_code(), 1);
721 return init.result.get();
724 #if !defined(BOOST_ASIO_NO_DEPRECATED)
725 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
726 typename Iterator, typename IteratorConnectHandler>
727 inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
728 void (boost::system::error_code, Iterator))
729 async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
730 Iterator begin, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
731 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
733 // If you get an error on the following line it means that your handler does
734 // not meet the documented type requirements for a IteratorConnectHandler.
735 BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
736 IteratorConnectHandler, handler, Iterator) type_check;
738 async_completion<IteratorConnectHandler,
739 void (boost::system::error_code, Iterator)> init(handler);
741 detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
742 detail::default_connect_condition, BOOST_ASIO_HANDLER_TYPE(
743 IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
744 begin, Iterator(), detail::default_connect_condition(),
745 init.completion_handler)(boost::system::error_code(), 1);
747 return init.result.get();
749 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
751 template <typename Protocol BOOST_ASIO_SVC_TPARAM,
752 typename Iterator, typename IteratorConnectHandler>
753 inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
754 void (boost::system::error_code, Iterator))
755 async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
756 Iterator begin, Iterator end,
757 BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
759 // If you get an error on the following line it means that your handler does
760 // not meet the documented type requirements for a IteratorConnectHandler.
761 BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
762 IteratorConnectHandler, handler, Iterator) type_check;
764 async_completion<IteratorConnectHandler,
765 void (boost::system::error_code, Iterator)> init(handler);
767 detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
768 detail::default_connect_condition, BOOST_ASIO_HANDLER_TYPE(
769 IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
770 begin, end, detail::default_connect_condition(),
771 init.completion_handler)(boost::system::error_code(), 1);
773 return init.result.get();
776 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
777 typename ConnectCondition, typename RangeConnectHandler>
778 inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
779 void (boost::system::error_code, typename Protocol::endpoint))
780 async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
781 const EndpointSequence& endpoints, ConnectCondition connect_condition,
782 BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
783 typename enable_if<is_endpoint_sequence<
784 EndpointSequence>::value>::type*)
786 // If you get an error on the following line it means that your handler does
787 // not meet the documented type requirements for a RangeConnectHandler.
788 BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK(
789 RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
791 async_completion<RangeConnectHandler,
792 void (boost::system::error_code, typename Protocol::endpoint)>
795 detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
796 ConnectCondition, BOOST_ASIO_HANDLER_TYPE(RangeConnectHandler,
797 void (boost::system::error_code, typename Protocol::endpoint))>(s,
798 endpoints, connect_condition, init.completion_handler)(
799 boost::system::error_code(), 1);
801 return init.result.get();
804 #if !defined(BOOST_ASIO_NO_DEPRECATED)
805 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
806 typename ConnectCondition, typename IteratorConnectHandler>
807 inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
808 void (boost::system::error_code, Iterator))
809 async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
810 Iterator begin, ConnectCondition connect_condition,
811 BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
812 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
814 // If you get an error on the following line it means that your handler does
815 // not meet the documented type requirements for a IteratorConnectHandler.
816 BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
817 IteratorConnectHandler, handler, Iterator) type_check;
819 async_completion<IteratorConnectHandler,
820 void (boost::system::error_code, Iterator)> init(handler);
822 detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
823 ConnectCondition, BOOST_ASIO_HANDLER_TYPE(
824 IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
825 begin, Iterator(), connect_condition, init.completion_handler)(
826 boost::system::error_code(), 1);
828 return init.result.get();
830 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
832 template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
833 typename ConnectCondition, typename IteratorConnectHandler>
834 inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
835 void (boost::system::error_code, Iterator))
836 async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
837 Iterator begin, Iterator end, ConnectCondition connect_condition,
838 BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
840 // If you get an error on the following line it means that your handler does
841 // not meet the documented type requirements for a IteratorConnectHandler.
842 BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
843 IteratorConnectHandler, handler, Iterator) type_check;
845 async_completion<IteratorConnectHandler,
846 void (boost::system::error_code, Iterator)> init(handler);
848 detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
849 ConnectCondition, BOOST_ASIO_HANDLER_TYPE(
850 IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
851 begin, end, connect_condition, init.completion_handler)(
852 boost::system::error_code(), 1);
854 return init.result.get();
860 #include <boost/asio/detail/pop_options.hpp>
862 #endif // BOOST_ASIO_IMPL_CONNECT_HPP