File indexing completed on 2025-01-18 09:28:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_IMPL_CONNECT_HPP
0012 #define BOOST_ASIO_IMPL_CONNECT_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <algorithm>
0019 #include <boost/asio/associator.hpp>
0020 #include <boost/asio/detail/base_from_cancellation_state.hpp>
0021 #include <boost/asio/detail/bind_handler.hpp>
0022 #include <boost/asio/detail/handler_cont_helpers.hpp>
0023 #include <boost/asio/detail/handler_tracking.hpp>
0024 #include <boost/asio/detail/handler_type_requirements.hpp>
0025 #include <boost/asio/detail/non_const_lvalue.hpp>
0026 #include <boost/asio/detail/throw_error.hpp>
0027 #include <boost/asio/detail/type_traits.hpp>
0028 #include <boost/asio/error.hpp>
0029 #include <boost/asio/post.hpp>
0030
0031 #include <boost/asio/detail/push_options.hpp>
0032
0033 namespace boost {
0034 namespace asio {
0035
0036 namespace detail
0037 {
0038 struct default_connect_condition
0039 {
0040 template <typename Endpoint>
0041 bool operator()(const boost::system::error_code&, const Endpoint&)
0042 {
0043 return true;
0044 }
0045 };
0046
0047 template <typename Protocol, typename Iterator>
0048 inline typename Protocol::endpoint deref_connect_result(
0049 Iterator iter, boost::system::error_code& ec)
0050 {
0051 return ec ? typename Protocol::endpoint() : *iter;
0052 }
0053
0054 template <typename T, typename Iterator>
0055 struct legacy_connect_condition_helper : T
0056 {
0057 typedef char (*fallback_func_type)(...);
0058 operator fallback_func_type() const;
0059 };
0060
0061 template <typename R, typename Arg1, typename Arg2, typename Iterator>
0062 struct legacy_connect_condition_helper<R (*)(Arg1, Arg2), Iterator>
0063 {
0064 R operator()(Arg1, Arg2) const;
0065 char operator()(...) const;
0066 };
0067
0068 template <typename T, typename Iterator>
0069 struct is_legacy_connect_condition
0070 {
0071 static char asio_connect_condition_check(char);
0072 static char (&asio_connect_condition_check(Iterator))[2];
0073
0074 static const bool value =
0075 sizeof(asio_connect_condition_check(
0076 (declval<legacy_connect_condition_helper<T, Iterator>>())(
0077 declval<const boost::system::error_code>(),
0078 declval<const Iterator>()))) != 1;
0079 };
0080
0081 template <typename ConnectCondition, typename Iterator>
0082 inline Iterator call_connect_condition(ConnectCondition& connect_condition,
0083 const boost::system::error_code& ec, Iterator next, Iterator end,
0084 enable_if_t<is_legacy_connect_condition<
0085 ConnectCondition, Iterator>::value>* = 0)
0086 {
0087 if (next != end)
0088 return connect_condition(ec, next);
0089 return end;
0090 }
0091
0092 template <typename ConnectCondition, typename Iterator>
0093 inline Iterator call_connect_condition(ConnectCondition& connect_condition,
0094 const boost::system::error_code& ec, Iterator next, Iterator end,
0095 enable_if_t<!is_legacy_connect_condition<
0096 ConnectCondition, Iterator>::value>* = 0)
0097 {
0098 for (;next != end; ++next)
0099 if (connect_condition(ec, *next))
0100 return next;
0101 return end;
0102 }
0103 }
0104
0105 template <typename Protocol, typename Executor, typename EndpointSequence>
0106 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0107 const EndpointSequence& endpoints,
0108 constraint_t<is_endpoint_sequence<EndpointSequence>::value>)
0109 {
0110 boost::system::error_code ec;
0111 typename Protocol::endpoint result = connect(s, endpoints, ec);
0112 boost::asio::detail::throw_error(ec, "connect");
0113 return result;
0114 }
0115
0116 template <typename Protocol, typename Executor, typename EndpointSequence>
0117 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0118 const EndpointSequence& endpoints, boost::system::error_code& ec,
0119 constraint_t<is_endpoint_sequence<EndpointSequence>::value>)
0120 {
0121 return detail::deref_connect_result<Protocol>(
0122 connect(s, endpoints.begin(), endpoints.end(),
0123 detail::default_connect_condition(), ec), ec);
0124 }
0125
0126 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0127 template <typename Protocol, typename Executor, typename Iterator>
0128 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0129 constraint_t<!is_endpoint_sequence<Iterator>::value>)
0130 {
0131 boost::system::error_code ec;
0132 Iterator result = connect(s, begin, ec);
0133 boost::asio::detail::throw_error(ec, "connect");
0134 return result;
0135 }
0136
0137 template <typename Protocol, typename Executor, typename Iterator>
0138 inline Iterator connect(basic_socket<Protocol, Executor>& s,
0139 Iterator begin, boost::system::error_code& ec,
0140 constraint_t<!is_endpoint_sequence<Iterator>::value>)
0141 {
0142 return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);
0143 }
0144 #endif
0145
0146 template <typename Protocol, typename Executor, typename Iterator>
0147 Iterator connect(basic_socket<Protocol, Executor>& s,
0148 Iterator begin, Iterator end)
0149 {
0150 boost::system::error_code ec;
0151 Iterator result = connect(s, begin, end, ec);
0152 boost::asio::detail::throw_error(ec, "connect");
0153 return result;
0154 }
0155
0156 template <typename Protocol, typename Executor, typename Iterator>
0157 inline Iterator connect(basic_socket<Protocol, Executor>& s,
0158 Iterator begin, Iterator end, boost::system::error_code& ec)
0159 {
0160 return connect(s, begin, end, detail::default_connect_condition(), ec);
0161 }
0162
0163 template <typename Protocol, typename Executor,
0164 typename EndpointSequence, typename ConnectCondition>
0165 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0166 const EndpointSequence& endpoints, ConnectCondition connect_condition,
0167 constraint_t<is_endpoint_sequence<EndpointSequence>::value>)
0168 {
0169 boost::system::error_code ec;
0170 typename Protocol::endpoint result = connect(
0171 s, endpoints, connect_condition, ec);
0172 boost::asio::detail::throw_error(ec, "connect");
0173 return result;
0174 }
0175
0176 template <typename Protocol, typename Executor,
0177 typename EndpointSequence, typename ConnectCondition>
0178 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0179 const EndpointSequence& endpoints, ConnectCondition connect_condition,
0180 boost::system::error_code& ec,
0181 constraint_t<is_endpoint_sequence<EndpointSequence>::value>)
0182 {
0183 return detail::deref_connect_result<Protocol>(
0184 connect(s, endpoints.begin(), endpoints.end(),
0185 connect_condition, ec), ec);
0186 }
0187
0188 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0189 template <typename Protocol, typename Executor,
0190 typename Iterator, typename ConnectCondition>
0191 Iterator connect(basic_socket<Protocol, Executor>& s,
0192 Iterator begin, ConnectCondition connect_condition,
0193 constraint_t<!is_endpoint_sequence<Iterator>::value>)
0194 {
0195 boost::system::error_code ec;
0196 Iterator result = connect(s, begin, connect_condition, ec);
0197 boost::asio::detail::throw_error(ec, "connect");
0198 return result;
0199 }
0200
0201 template <typename Protocol, typename Executor,
0202 typename Iterator, typename ConnectCondition>
0203 inline Iterator connect(basic_socket<Protocol, Executor>& s,
0204 Iterator begin, ConnectCondition connect_condition,
0205 boost::system::error_code& ec,
0206 constraint_t<!is_endpoint_sequence<Iterator>::value>)
0207 {
0208 return connect(s, begin, Iterator(), connect_condition, ec);
0209 }
0210 #endif
0211
0212 template <typename Protocol, typename Executor,
0213 typename Iterator, typename ConnectCondition>
0214 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0215 Iterator end, ConnectCondition connect_condition)
0216 {
0217 boost::system::error_code ec;
0218 Iterator result = connect(s, begin, end, connect_condition, ec);
0219 boost::asio::detail::throw_error(ec, "connect");
0220 return result;
0221 }
0222
0223 template <typename Protocol, typename Executor,
0224 typename Iterator, typename ConnectCondition>
0225 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0226 Iterator end, ConnectCondition connect_condition,
0227 boost::system::error_code& ec)
0228 {
0229 ec = boost::system::error_code();
0230
0231 for (Iterator iter = begin; iter != end; ++iter)
0232 {
0233 iter = (detail::call_connect_condition(connect_condition, ec, iter, end));
0234 if (iter != end)
0235 {
0236 s.close(ec);
0237 s.connect(*iter, ec);
0238 if (!ec)
0239 return iter;
0240 }
0241 else
0242 break;
0243 }
0244
0245 if (!ec)
0246 ec = boost::asio::error::not_found;
0247
0248 return end;
0249 }
0250
0251 namespace detail
0252 {
0253
0254 template <typename ConnectCondition>
0255 class base_from_connect_condition
0256 {
0257 protected:
0258 explicit base_from_connect_condition(
0259 const ConnectCondition& connect_condition)
0260 : connect_condition_(connect_condition)
0261 {
0262 }
0263
0264 template <typename Iterator>
0265 void check_condition(const boost::system::error_code& ec,
0266 Iterator& iter, Iterator& end)
0267 {
0268 iter = detail::call_connect_condition(connect_condition_, ec, iter, end);
0269 }
0270
0271 private:
0272 ConnectCondition connect_condition_;
0273 };
0274
0275
0276
0277 template <>
0278 class base_from_connect_condition<default_connect_condition>
0279 {
0280 protected:
0281 explicit base_from_connect_condition(const default_connect_condition&)
0282 {
0283 }
0284
0285 template <typename Iterator>
0286 void check_condition(const boost::system::error_code&, Iterator&, Iterator&)
0287 {
0288 }
0289 };
0290
0291 template <typename Protocol, typename Executor, typename EndpointSequence,
0292 typename ConnectCondition, typename RangeConnectHandler>
0293 class range_connect_op
0294 : public base_from_cancellation_state<RangeConnectHandler>,
0295 base_from_connect_condition<ConnectCondition>
0296 {
0297 public:
0298 range_connect_op(basic_socket<Protocol, Executor>& sock,
0299 const EndpointSequence& endpoints,
0300 const ConnectCondition& connect_condition,
0301 RangeConnectHandler& handler)
0302 : base_from_cancellation_state<RangeConnectHandler>(
0303 handler, enable_partial_cancellation()),
0304 base_from_connect_condition<ConnectCondition>(connect_condition),
0305 socket_(sock),
0306 endpoints_(endpoints),
0307 index_(0),
0308 start_(0),
0309 handler_(static_cast<RangeConnectHandler&&>(handler))
0310 {
0311 }
0312
0313 range_connect_op(const range_connect_op& other)
0314 : base_from_cancellation_state<RangeConnectHandler>(other),
0315 base_from_connect_condition<ConnectCondition>(other),
0316 socket_(other.socket_),
0317 endpoints_(other.endpoints_),
0318 index_(other.index_),
0319 start_(other.start_),
0320 handler_(other.handler_)
0321 {
0322 }
0323
0324 range_connect_op(range_connect_op&& other)
0325 : base_from_cancellation_state<RangeConnectHandler>(
0326 static_cast<base_from_cancellation_state<RangeConnectHandler>&&>(
0327 other)),
0328 base_from_connect_condition<ConnectCondition>(other),
0329 socket_(other.socket_),
0330 endpoints_(other.endpoints_),
0331 index_(other.index_),
0332 start_(other.start_),
0333 handler_(static_cast<RangeConnectHandler&&>(other.handler_))
0334 {
0335 }
0336
0337 void operator()(boost::system::error_code ec, int start = 0)
0338 {
0339 this->process(ec, start,
0340 const_cast<const EndpointSequence&>(endpoints_).begin(),
0341 const_cast<const EndpointSequence&>(endpoints_).end());
0342 }
0343
0344
0345 template <typename Iterator>
0346 void process(boost::system::error_code ec,
0347 int start, Iterator begin, Iterator end)
0348 {
0349 Iterator iter = begin;
0350 std::advance(iter, index_);
0351
0352 switch (start_ = start)
0353 {
0354 case 1:
0355 for (;;)
0356 {
0357 this->check_condition(ec, iter, end);
0358 index_ = std::distance(begin, iter);
0359
0360 if (iter != end)
0361 {
0362 socket_.close(ec);
0363 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
0364 socket_.async_connect(*iter,
0365 static_cast<range_connect_op&&>(*this));
0366 return;
0367 }
0368
0369 if (start)
0370 {
0371 ec = boost::asio::error::not_found;
0372 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
0373 boost::asio::post(socket_.get_executor(),
0374 detail::bind_handler(
0375 static_cast<range_connect_op&&>(*this), ec));
0376 return;
0377 }
0378
0379 default:
0380
0381 if (iter == end)
0382 break;
0383
0384 if (!socket_.is_open())
0385 {
0386 ec = boost::asio::error::operation_aborted;
0387 break;
0388 }
0389
0390 if (!ec)
0391 break;
0392
0393 if (this->cancelled() != cancellation_type::none)
0394 {
0395 ec = boost::asio::error::operation_aborted;
0396 break;
0397 }
0398
0399 ++iter;
0400 ++index_;
0401 }
0402
0403 static_cast<RangeConnectHandler&&>(handler_)(
0404 static_cast<const boost::system::error_code&>(ec),
0405 static_cast<const typename Protocol::endpoint&>(
0406 ec || iter == end ? typename Protocol::endpoint() : *iter));
0407 }
0408 }
0409
0410 basic_socket<Protocol, Executor>& socket_;
0411 EndpointSequence endpoints_;
0412 std::size_t index_;
0413 int start_;
0414 RangeConnectHandler handler_;
0415 };
0416
0417 template <typename Protocol, typename Executor, typename EndpointSequence,
0418 typename ConnectCondition, typename RangeConnectHandler>
0419 inline bool asio_handler_is_continuation(
0420 range_connect_op<Protocol, Executor, EndpointSequence,
0421 ConnectCondition, RangeConnectHandler>* this_handler)
0422 {
0423 return boost_asio_handler_cont_helpers::is_continuation(
0424 this_handler->handler_);
0425 }
0426
0427 template <typename Protocol, typename Executor>
0428 class initiate_async_range_connect
0429 {
0430 public:
0431 typedef Executor executor_type;
0432
0433 explicit initiate_async_range_connect(basic_socket<Protocol, Executor>& s)
0434 : socket_(s)
0435 {
0436 }
0437
0438 executor_type get_executor() const noexcept
0439 {
0440 return socket_.get_executor();
0441 }
0442
0443 template <typename RangeConnectHandler,
0444 typename EndpointSequence, typename ConnectCondition>
0445 void operator()(RangeConnectHandler&& handler,
0446 const EndpointSequence& endpoints,
0447 const ConnectCondition& connect_condition) const
0448 {
0449
0450
0451
0452 BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK(RangeConnectHandler,
0453 handler, typename Protocol::endpoint) type_check;
0454
0455 non_const_lvalue<RangeConnectHandler> handler2(handler);
0456 range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,
0457 decay_t<RangeConnectHandler>>(socket_, endpoints,
0458 connect_condition, handler2.value)(boost::system::error_code(), 1);
0459 }
0460
0461 private:
0462 basic_socket<Protocol, Executor>& socket_;
0463 };
0464
0465 template <typename Protocol, typename Executor, typename Iterator,
0466 typename ConnectCondition, typename IteratorConnectHandler>
0467 class iterator_connect_op
0468 : public base_from_cancellation_state<IteratorConnectHandler>,
0469 base_from_connect_condition<ConnectCondition>
0470 {
0471 public:
0472 iterator_connect_op(basic_socket<Protocol, Executor>& sock,
0473 const Iterator& begin, const Iterator& end,
0474 const ConnectCondition& connect_condition,
0475 IteratorConnectHandler& handler)
0476 : base_from_cancellation_state<IteratorConnectHandler>(
0477 handler, enable_partial_cancellation()),
0478 base_from_connect_condition<ConnectCondition>(connect_condition),
0479 socket_(sock),
0480 iter_(begin),
0481 end_(end),
0482 start_(0),
0483 handler_(static_cast<IteratorConnectHandler&&>(handler))
0484 {
0485 }
0486
0487 iterator_connect_op(const iterator_connect_op& other)
0488 : base_from_cancellation_state<IteratorConnectHandler>(other),
0489 base_from_connect_condition<ConnectCondition>(other),
0490 socket_(other.socket_),
0491 iter_(other.iter_),
0492 end_(other.end_),
0493 start_(other.start_),
0494 handler_(other.handler_)
0495 {
0496 }
0497
0498 iterator_connect_op(iterator_connect_op&& other)
0499 : base_from_cancellation_state<IteratorConnectHandler>(
0500 static_cast<base_from_cancellation_state<IteratorConnectHandler>&&>(
0501 other)),
0502 base_from_connect_condition<ConnectCondition>(other),
0503 socket_(other.socket_),
0504 iter_(other.iter_),
0505 end_(other.end_),
0506 start_(other.start_),
0507 handler_(static_cast<IteratorConnectHandler&&>(other.handler_))
0508 {
0509 }
0510
0511 void operator()(boost::system::error_code ec, int start = 0)
0512 {
0513 switch (start_ = start)
0514 {
0515 case 1:
0516 for (;;)
0517 {
0518 this->check_condition(ec, iter_, end_);
0519
0520 if (iter_ != end_)
0521 {
0522 socket_.close(ec);
0523 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
0524 socket_.async_connect(*iter_,
0525 static_cast<iterator_connect_op&&>(*this));
0526 return;
0527 }
0528
0529 if (start)
0530 {
0531 ec = boost::asio::error::not_found;
0532 BOOST_ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));
0533 boost::asio::post(socket_.get_executor(),
0534 detail::bind_handler(
0535 static_cast<iterator_connect_op&&>(*this), ec));
0536 return;
0537 }
0538
0539 default:
0540
0541 if (iter_ == end_)
0542 break;
0543
0544 if (!socket_.is_open())
0545 {
0546 ec = boost::asio::error::operation_aborted;
0547 break;
0548 }
0549
0550 if (!ec)
0551 break;
0552
0553 if (this->cancelled() != cancellation_type::none)
0554 {
0555 ec = boost::asio::error::operation_aborted;
0556 break;
0557 }
0558
0559 ++iter_;
0560 }
0561
0562 static_cast<IteratorConnectHandler&&>(handler_)(
0563 static_cast<const boost::system::error_code&>(ec),
0564 static_cast<const Iterator&>(iter_));
0565 }
0566 }
0567
0568
0569 basic_socket<Protocol, Executor>& socket_;
0570 Iterator iter_;
0571 Iterator end_;
0572 int start_;
0573 IteratorConnectHandler handler_;
0574 };
0575
0576 template <typename Protocol, typename Executor, typename Iterator,
0577 typename ConnectCondition, typename IteratorConnectHandler>
0578 inline bool asio_handler_is_continuation(
0579 iterator_connect_op<Protocol, Executor, Iterator,
0580 ConnectCondition, IteratorConnectHandler>* this_handler)
0581 {
0582 return boost_asio_handler_cont_helpers::is_continuation(
0583 this_handler->handler_);
0584 }
0585
0586 template <typename Protocol, typename Executor>
0587 class initiate_async_iterator_connect
0588 {
0589 public:
0590 typedef Executor executor_type;
0591
0592 explicit initiate_async_iterator_connect(
0593 basic_socket<Protocol, Executor>& s)
0594 : socket_(s)
0595 {
0596 }
0597
0598 executor_type get_executor() const noexcept
0599 {
0600 return socket_.get_executor();
0601 }
0602
0603 template <typename IteratorConnectHandler,
0604 typename Iterator, typename ConnectCondition>
0605 void operator()(IteratorConnectHandler&& handler,
0606 Iterator begin, Iterator end,
0607 const ConnectCondition& connect_condition) const
0608 {
0609
0610
0611
0612 BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
0613 IteratorConnectHandler, handler, Iterator) type_check;
0614
0615 non_const_lvalue<IteratorConnectHandler> handler2(handler);
0616 iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,
0617 decay_t<IteratorConnectHandler>>(socket_, begin, end,
0618 connect_condition, handler2.value)(boost::system::error_code(), 1);
0619 }
0620
0621 private:
0622 basic_socket<Protocol, Executor>& socket_;
0623 };
0624 }
0625
0626 #if !defined(GENERATING_DOCUMENTATION)
0627
0628 template <template <typename, typename> class Associator,
0629 typename Protocol, typename Executor, typename EndpointSequence,
0630 typename ConnectCondition, typename RangeConnectHandler,
0631 typename DefaultCandidate>
0632 struct associator<Associator,
0633 detail::range_connect_op<Protocol, Executor,
0634 EndpointSequence, ConnectCondition, RangeConnectHandler>,
0635 DefaultCandidate>
0636 : Associator<RangeConnectHandler, DefaultCandidate>
0637 {
0638 static typename Associator<RangeConnectHandler, DefaultCandidate>::type get(
0639 const detail::range_connect_op<Protocol, Executor, EndpointSequence,
0640 ConnectCondition, RangeConnectHandler>& h) noexcept
0641 {
0642 return Associator<RangeConnectHandler, DefaultCandidate>::get(h.handler_);
0643 }
0644
0645 static auto get(
0646 const detail::range_connect_op<Protocol, Executor,
0647 EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
0648 const DefaultCandidate& c) noexcept
0649 -> decltype(
0650 Associator<RangeConnectHandler, DefaultCandidate>::get(
0651 h.handler_, c))
0652 {
0653 return Associator<RangeConnectHandler, DefaultCandidate>::get(
0654 h.handler_, c);
0655 }
0656 };
0657
0658 template <template <typename, typename> class Associator,
0659 typename Protocol, typename Executor, typename Iterator,
0660 typename ConnectCondition, typename IteratorConnectHandler,
0661 typename DefaultCandidate>
0662 struct associator<Associator,
0663 detail::iterator_connect_op<Protocol, Executor,
0664 Iterator, ConnectCondition, IteratorConnectHandler>,
0665 DefaultCandidate>
0666 : Associator<IteratorConnectHandler, DefaultCandidate>
0667 {
0668 static typename Associator<IteratorConnectHandler, DefaultCandidate>::type
0669 get(const detail::iterator_connect_op<Protocol, Executor, Iterator,
0670 ConnectCondition, IteratorConnectHandler>& h) noexcept
0671 {
0672 return Associator<IteratorConnectHandler, DefaultCandidate>::get(
0673 h.handler_);
0674 }
0675
0676 static auto get(
0677 const detail::iterator_connect_op<Protocol, Executor,
0678 Iterator, ConnectCondition, IteratorConnectHandler>& h,
0679 const DefaultCandidate& c) noexcept
0680 -> decltype(
0681 Associator<IteratorConnectHandler, DefaultCandidate>::get(
0682 h.handler_, c))
0683 {
0684 return Associator<IteratorConnectHandler, DefaultCandidate>::get(
0685 h.handler_, c);
0686 }
0687 };
0688
0689 #endif
0690
0691 template <typename Protocol, typename Executor, typename EndpointSequence,
0692 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0693 typename Protocol::endpoint)) RangeConnectToken>
0694 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0695 const EndpointSequence& endpoints, RangeConnectToken&& token,
0696 constraint_t<is_endpoint_sequence<EndpointSequence>::value>)
0697 -> decltype(
0698 async_initiate<RangeConnectToken,
0699 void (boost::system::error_code, typename Protocol::endpoint)>(
0700 declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
0701 token, endpoints, declval<detail::default_connect_condition>()))
0702 {
0703 return async_initiate<RangeConnectToken,
0704 void (boost::system::error_code, typename Protocol::endpoint)>(
0705 detail::initiate_async_range_connect<Protocol, Executor>(s),
0706 token, endpoints, detail::default_connect_condition());
0707 }
0708
0709 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0710 template <typename Protocol, typename Executor, typename Iterator,
0711 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0712 Iterator)) IteratorConnectToken>
0713 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0714 Iterator begin, IteratorConnectToken&& token,
0715 constraint_t<!is_endpoint_sequence<Iterator>::value>)
0716 -> decltype(
0717 async_initiate<IteratorConnectToken,
0718 void (boost::system::error_code, Iterator)>(
0719 declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
0720 token, begin, Iterator(), declval<detail::default_connect_condition>()))
0721 {
0722 return async_initiate<IteratorConnectToken,
0723 void (boost::system::error_code, Iterator)>(
0724 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
0725 token, begin, Iterator(), detail::default_connect_condition());
0726 }
0727 #endif
0728
0729 template <typename Protocol, typename Executor, typename Iterator,
0730 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0731 Iterator)) IteratorConnectToken>
0732 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0733 Iterator begin, Iterator end, IteratorConnectToken&& token)
0734 -> decltype(
0735 async_initiate<IteratorConnectToken,
0736 void (boost::system::error_code, Iterator)>(
0737 declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
0738 token, begin, end, declval<detail::default_connect_condition>()))
0739 {
0740 return async_initiate<IteratorConnectToken,
0741 void (boost::system::error_code, Iterator)>(
0742 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
0743 token, begin, end, detail::default_connect_condition());
0744 }
0745
0746 template <typename Protocol, typename Executor,
0747 typename EndpointSequence, typename ConnectCondition,
0748 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0749 typename Protocol::endpoint)) RangeConnectToken>
0750 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0751 const EndpointSequence& endpoints, ConnectCondition connect_condition,
0752 RangeConnectToken&& token,
0753 constraint_t<is_endpoint_sequence<EndpointSequence>::value>)
0754 -> decltype(
0755 async_initiate<RangeConnectToken,
0756 void (boost::system::error_code, typename Protocol::endpoint)>(
0757 declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
0758 token, endpoints, connect_condition))
0759 {
0760 return async_initiate<RangeConnectToken,
0761 void (boost::system::error_code, typename Protocol::endpoint)>(
0762 detail::initiate_async_range_connect<Protocol, Executor>(s),
0763 token, endpoints, connect_condition);
0764 }
0765
0766 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0767 template <typename Protocol, typename Executor,
0768 typename Iterator, typename ConnectCondition,
0769 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0770 Iterator)) IteratorConnectToken>
0771 inline auto async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0772 ConnectCondition connect_condition, IteratorConnectToken&& token,
0773 constraint_t<!is_endpoint_sequence<Iterator>::value>)
0774 -> decltype(
0775 async_initiate<IteratorConnectToken,
0776 void (boost::system::error_code, Iterator)>(
0777 declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
0778 token, begin, Iterator(), connect_condition))
0779 {
0780 return async_initiate<IteratorConnectToken,
0781 void (boost::system::error_code, Iterator)>(
0782 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
0783 token, begin, Iterator(), connect_condition);
0784 }
0785 #endif
0786
0787 template <typename Protocol, typename Executor,
0788 typename Iterator, typename ConnectCondition,
0789 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0790 Iterator)) IteratorConnectToken>
0791 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0792 Iterator begin, Iterator end, ConnectCondition connect_condition,
0793 IteratorConnectToken&& token)
0794 -> decltype(
0795 async_initiate<IteratorConnectToken,
0796 void (boost::system::error_code, Iterator)>(
0797 declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
0798 token, begin, end, connect_condition))
0799 {
0800 return async_initiate<IteratorConnectToken,
0801 void (boost::system::error_code, Iterator)>(
0802 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
0803 token, begin, end, connect_condition);
0804 }
0805
0806 }
0807 }
0808
0809 #include <boost/asio/detail/pop_options.hpp>
0810
0811 #endif