Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

connect.hpp 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. //
  2. // impl/connect.hpp
  3. // ~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  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)
  9. //
  10. #ifndef ASIO_IMPL_CONNECT_HPP
  11. #define ASIO_IMPL_CONNECT_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <algorithm>
  16. #include "asio/associated_allocator.hpp"
  17. #include "asio/associated_executor.hpp"
  18. #include "asio/detail/bind_handler.hpp"
  19. #include "asio/detail/consuming_buffers.hpp"
  20. #include "asio/detail/handler_alloc_helpers.hpp"
  21. #include "asio/detail/handler_cont_helpers.hpp"
  22. #include "asio/detail/handler_invoke_helpers.hpp"
  23. #include "asio/detail/handler_type_requirements.hpp"
  24. #include "asio/detail/throw_error.hpp"
  25. #include "asio/error.hpp"
  26. #include "asio/post.hpp"
  27. #include "asio/detail/push_options.hpp"
  28. namespace asio {
  29. namespace detail
  30. {
  31. struct default_connect_condition
  32. {
  33. template <typename Endpoint>
  34. bool operator()(const asio::error_code&, const Endpoint&)
  35. {
  36. return true;
  37. }
  38. };
  39. }
  40. template <typename Protocol, typename SocketService, typename EndpointSequence>
  41. typename Protocol::endpoint connect(basic_socket<Protocol, SocketService>& s,
  42. const EndpointSequence& endpoints,
  43. typename enable_if<is_endpoint_sequence<
  44. EndpointSequence>::value>::type*)
  45. {
  46. asio::error_code ec;
  47. typename Protocol::endpoint result = connect(s, endpoints, ec);
  48. asio::detail::throw_error(ec, "connect");
  49. return result;
  50. }
  51. template <typename Protocol, typename SocketService, typename EndpointSequence>
  52. typename Protocol::endpoint connect(basic_socket<Protocol, SocketService>& s,
  53. const EndpointSequence& endpoints, asio::error_code& ec,
  54. typename enable_if<is_endpoint_sequence<
  55. EndpointSequence>::value>::type*)
  56. {
  57. typename EndpointSequence::iterator iter = connect(
  58. s, endpoints.begin(), endpoints.end(),
  59. detail::default_connect_condition(), ec);
  60. return ec ? typename Protocol::endpoint() : *iter;
  61. }
  62. #if !defined(ASIO_NO_DEPRECATED)
  63. template <typename Protocol, typename SocketService, typename Iterator>
  64. Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
  65. typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
  66. {
  67. asio::error_code ec;
  68. Iterator result = connect(s, begin, ec);
  69. asio::detail::throw_error(ec, "connect");
  70. return result;
  71. }
  72. template <typename Protocol, typename SocketService, typename Iterator>
  73. inline Iterator connect(basic_socket<Protocol, SocketService>& s,
  74. Iterator begin, asio::error_code& ec,
  75. typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
  76. {
  77. return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);
  78. }
  79. #endif // !defined(ASIO_NO_DEPRECATED)
  80. template <typename Protocol, typename SocketService, typename Iterator>
  81. Iterator connect(basic_socket<Protocol, SocketService>& s,
  82. Iterator begin, Iterator end)
  83. {
  84. asio::error_code ec;
  85. Iterator result = connect(s, begin, end, ec);
  86. asio::detail::throw_error(ec, "connect");
  87. return result;
  88. }
  89. template <typename Protocol, typename SocketService, typename Iterator>
  90. inline Iterator connect(basic_socket<Protocol, SocketService>& s,
  91. Iterator begin, Iterator end, asio::error_code& ec)
  92. {
  93. return connect(s, begin, end, detail::default_connect_condition(), ec);
  94. }
  95. template <typename Protocol, typename SocketService,
  96. typename EndpointSequence, typename ConnectCondition>
  97. typename Protocol::endpoint connect(basic_socket<Protocol, SocketService>& s,
  98. const EndpointSequence& endpoints, ConnectCondition connect_condition,
  99. typename enable_if<is_endpoint_sequence<
  100. EndpointSequence>::value>::type*)
  101. {
  102. asio::error_code ec;
  103. typename Protocol::endpoint result = connect(
  104. s, endpoints, connect_condition, ec);
  105. asio::detail::throw_error(ec, "connect");
  106. return result;
  107. }
  108. template <typename Protocol, typename SocketService,
  109. typename EndpointSequence, typename ConnectCondition>
  110. typename Protocol::endpoint connect(basic_socket<Protocol, SocketService>& s,
  111. const EndpointSequence& endpoints, ConnectCondition connect_condition,
  112. asio::error_code& ec,
  113. typename enable_if<is_endpoint_sequence<
  114. EndpointSequence>::value>::type*)
  115. {
  116. typename EndpointSequence::iterator iter = connect(
  117. s, endpoints.begin(), endpoints.end(), connect_condition, ec);
  118. return ec ? typename Protocol::endpoint() : *iter;
  119. }
  120. #if !defined(ASIO_NO_DEPRECATED)
  121. template <typename Protocol, typename SocketService,
  122. typename Iterator, typename ConnectCondition>
  123. Iterator connect(basic_socket<Protocol, SocketService>& s,
  124. Iterator begin, ConnectCondition connect_condition,
  125. typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
  126. {
  127. asio::error_code ec;
  128. Iterator result = connect(s, begin, connect_condition, ec);
  129. asio::detail::throw_error(ec, "connect");
  130. return result;
  131. }
  132. template <typename Protocol, typename SocketService,
  133. typename Iterator, typename ConnectCondition>
  134. inline Iterator connect(basic_socket<Protocol, SocketService>& s,
  135. Iterator begin, ConnectCondition connect_condition,
  136. asio::error_code& ec,
  137. typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
  138. {
  139. return connect(s, begin, Iterator(), connect_condition, ec);
  140. }
  141. #endif // !defined(ASIO_NO_DEPRECATED)
  142. template <typename Protocol, typename SocketService,
  143. typename Iterator, typename ConnectCondition>
  144. Iterator connect(basic_socket<Protocol, SocketService>& s,
  145. Iterator begin, Iterator end, ConnectCondition connect_condition)
  146. {
  147. asio::error_code ec;
  148. Iterator result = connect(s, begin, end, connect_condition, ec);
  149. asio::detail::throw_error(ec, "connect");
  150. return result;
  151. }
  152. template <typename Protocol, typename SocketService,
  153. typename Iterator, typename ConnectCondition>
  154. Iterator connect(basic_socket<Protocol, SocketService>& s,
  155. Iterator begin, Iterator end, ConnectCondition connect_condition,
  156. asio::error_code& ec)
  157. {
  158. ec = asio::error_code();
  159. for (Iterator iter = begin; iter != end; ++iter)
  160. {
  161. if (connect_condition(ec, iter))
  162. {
  163. s.close(ec);
  164. s.connect(*iter, ec);
  165. if (!ec)
  166. return iter;
  167. }
  168. }
  169. if (!ec)
  170. ec = asio::error::not_found;
  171. return end;
  172. }
  173. namespace detail
  174. {
  175. // Enable the empty base class optimisation for the connect condition.
  176. template <typename ConnectCondition>
  177. class base_from_connect_condition
  178. {
  179. protected:
  180. explicit base_from_connect_condition(
  181. const ConnectCondition& connect_condition)
  182. : connect_condition_(connect_condition)
  183. {
  184. }
  185. template <typename Endpoint>
  186. bool check_condition(const asio::error_code& ec,
  187. const Endpoint& endpoint)
  188. {
  189. return connect_condition_(ec, endpoint);
  190. }
  191. private:
  192. ConnectCondition connect_condition_;
  193. };
  194. // The default_connect_condition implementation is essentially a no-op. This
  195. // template specialisation lets us eliminate all costs associated with it.
  196. template <>
  197. class base_from_connect_condition<default_connect_condition>
  198. {
  199. protected:
  200. explicit base_from_connect_condition(const default_connect_condition&)
  201. {
  202. }
  203. template <typename Endpoint>
  204. bool check_condition(const asio::error_code&, const Endpoint&)
  205. {
  206. return true;
  207. }
  208. };
  209. template <typename Protocol, typename SocketService,
  210. typename EndpointSequence, typename ConnectCondition,
  211. typename RangeConnectHandler>
  212. class range_connect_op : base_from_connect_condition<ConnectCondition>
  213. {
  214. public:
  215. range_connect_op(basic_socket<Protocol, SocketService>& sock,
  216. const EndpointSequence& endpoints,
  217. const ConnectCondition& connect_condition,
  218. RangeConnectHandler& handler)
  219. : base_from_connect_condition<ConnectCondition>(connect_condition),
  220. socket_(sock),
  221. endpoints_(endpoints),
  222. index_(0),
  223. start_(0),
  224. handler_(ASIO_MOVE_CAST(RangeConnectHandler)(handler))
  225. {
  226. }
  227. #if defined(ASIO_HAS_MOVE)
  228. range_connect_op(const range_connect_op& other)
  229. : base_from_connect_condition<ConnectCondition>(other),
  230. socket_(other.socket_),
  231. endpoints_(other.endpoints_),
  232. index_(other.index_),
  233. start_(other.start_),
  234. handler_(other.handler_)
  235. {
  236. }
  237. range_connect_op(range_connect_op&& other)
  238. : base_from_connect_condition<ConnectCondition>(other),
  239. socket_(other.socket_),
  240. endpoints_(other.endpoints_),
  241. index_(other.index_),
  242. start_(other.start_),
  243. handler_(ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_))
  244. {
  245. }
  246. #endif // defined(ASIO_HAS_MOVE)
  247. void operator()(asio::error_code ec, int start = 0)
  248. {
  249. typename EndpointSequence::iterator iter = endpoints_.begin();
  250. std::advance(iter, index_);
  251. typename EndpointSequence::iterator end = endpoints_.end();
  252. switch (start_ = start)
  253. {
  254. case 1:
  255. for (;;)
  256. {
  257. for (; iter != end; ++iter, ++index_)
  258. if (this->check_condition(ec, *iter))
  259. break;
  260. if (iter != end)
  261. {
  262. socket_.close(ec);
  263. socket_.async_connect(*iter,
  264. ASIO_MOVE_CAST(range_connect_op)(*this));
  265. return;
  266. }
  267. if (start)
  268. {
  269. ec = asio::error::not_found;
  270. asio::post(socket_.get_executor(),
  271. detail::bind_handler(
  272. ASIO_MOVE_CAST(range_connect_op)(*this), ec));
  273. return;
  274. }
  275. default:
  276. if (iter == end)
  277. break;
  278. if (!socket_.is_open())
  279. {
  280. ec = asio::error::operation_aborted;
  281. break;
  282. }
  283. if (!ec)
  284. break;
  285. ++iter;
  286. ++index_;
  287. }
  288. handler_(static_cast<const asio::error_code&>(ec),
  289. static_cast<const typename Protocol::endpoint&>(
  290. ec || iter == end ? typename Protocol::endpoint() : *iter));
  291. }
  292. }
  293. //private:
  294. basic_socket<Protocol, SocketService>& socket_;
  295. EndpointSequence endpoints_;
  296. std::size_t index_;
  297. int start_;
  298. RangeConnectHandler handler_;
  299. };
  300. template <typename Protocol, typename SocketService,
  301. typename EndpointSequence, typename ConnectCondition,
  302. typename RangeConnectHandler>
  303. inline void* asio_handler_allocate(std::size_t size,
  304. range_connect_op<Protocol, SocketService, EndpointSequence,
  305. ConnectCondition, RangeConnectHandler>* this_handler)
  306. {
  307. return asio_handler_alloc_helpers::allocate(
  308. size, this_handler->handler_);
  309. }
  310. template <typename Protocol, typename SocketService,
  311. typename EndpointSequence, typename ConnectCondition,
  312. typename RangeConnectHandler>
  313. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  314. range_connect_op<Protocol, SocketService, EndpointSequence,
  315. ConnectCondition, RangeConnectHandler>* this_handler)
  316. {
  317. asio_handler_alloc_helpers::deallocate(
  318. pointer, size, this_handler->handler_);
  319. }
  320. template <typename Protocol, typename SocketService,
  321. typename EndpointSequence, typename ConnectCondition,
  322. typename RangeConnectHandler>
  323. inline bool asio_handler_is_continuation(
  324. range_connect_op<Protocol, SocketService, EndpointSequence,
  325. ConnectCondition, RangeConnectHandler>* this_handler)
  326. {
  327. return asio_handler_cont_helpers::is_continuation(
  328. this_handler->handler_);
  329. }
  330. template <typename Function, typename Protocol,
  331. typename SocketService, typename EndpointSequence,
  332. typename ConnectCondition, typename RangeConnectHandler>
  333. inline void asio_handler_invoke(Function& function,
  334. range_connect_op<Protocol, SocketService, EndpointSequence,
  335. ConnectCondition, RangeConnectHandler>* this_handler)
  336. {
  337. asio_handler_invoke_helpers::invoke(
  338. function, this_handler->handler_);
  339. }
  340. template <typename Function, typename Protocol,
  341. typename SocketService, typename EndpointSequence,
  342. typename ConnectCondition, typename RangeConnectHandler>
  343. inline void asio_handler_invoke(const Function& function,
  344. range_connect_op<Protocol, SocketService, EndpointSequence,
  345. ConnectCondition, RangeConnectHandler>* this_handler)
  346. {
  347. asio_handler_invoke_helpers::invoke(
  348. function, this_handler->handler_);
  349. }
  350. template <typename Protocol, typename SocketService, typename Iterator,
  351. typename ConnectCondition, typename IteratorConnectHandler>
  352. class iterator_connect_op : base_from_connect_condition<ConnectCondition>
  353. {
  354. public:
  355. iterator_connect_op(basic_socket<Protocol, SocketService>& sock,
  356. const Iterator& begin, const Iterator& end,
  357. const ConnectCondition& connect_condition,
  358. IteratorConnectHandler& handler)
  359. : base_from_connect_condition<ConnectCondition>(connect_condition),
  360. socket_(sock),
  361. iter_(begin),
  362. end_(end),
  363. start_(0),
  364. handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(handler))
  365. {
  366. }
  367. #if defined(ASIO_HAS_MOVE)
  368. iterator_connect_op(const iterator_connect_op& other)
  369. : base_from_connect_condition<ConnectCondition>(other),
  370. socket_(other.socket_),
  371. iter_(other.iter_),
  372. end_(other.end_),
  373. start_(other.start_),
  374. handler_(other.handler_)
  375. {
  376. }
  377. iterator_connect_op(iterator_connect_op&& other)
  378. : base_from_connect_condition<ConnectCondition>(other),
  379. socket_(other.socket_),
  380. iter_(other.iter_),
  381. end_(other.end_),
  382. start_(other.start_),
  383. handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_))
  384. {
  385. }
  386. #endif // defined(ASIO_HAS_MOVE)
  387. void operator()(asio::error_code ec, int start = 0)
  388. {
  389. switch (start_ = start)
  390. {
  391. case 1:
  392. for (;;)
  393. {
  394. for (; iter_ != end_; ++iter_)
  395. if (this->check_condition(ec, *iter_))
  396. break;
  397. if (iter_ != end_)
  398. {
  399. socket_.close(ec);
  400. socket_.async_connect(*iter_,
  401. ASIO_MOVE_CAST(iterator_connect_op)(*this));
  402. return;
  403. }
  404. if (start)
  405. {
  406. ec = asio::error::not_found;
  407. asio::post(socket_.get_executor(),
  408. detail::bind_handler(
  409. ASIO_MOVE_CAST(iterator_connect_op)(*this), ec));
  410. return;
  411. }
  412. default:
  413. if (iter_ == end_)
  414. break;
  415. if (!socket_.is_open())
  416. {
  417. ec = asio::error::operation_aborted;
  418. break;
  419. }
  420. if (!ec)
  421. break;
  422. ++iter_;
  423. }
  424. handler_(static_cast<const asio::error_code&>(ec),
  425. static_cast<const Iterator&>(iter_));
  426. }
  427. }
  428. //private:
  429. basic_socket<Protocol, SocketService>& socket_;
  430. Iterator iter_;
  431. Iterator end_;
  432. int start_;
  433. IteratorConnectHandler handler_;
  434. };
  435. template <typename Protocol, typename SocketService, typename Iterator,
  436. typename ConnectCondition, typename IteratorConnectHandler>
  437. inline void* asio_handler_allocate(std::size_t size,
  438. iterator_connect_op<Protocol, SocketService, Iterator,
  439. ConnectCondition, IteratorConnectHandler>* this_handler)
  440. {
  441. return asio_handler_alloc_helpers::allocate(
  442. size, this_handler->handler_);
  443. }
  444. template <typename Protocol, typename SocketService, typename Iterator,
  445. typename ConnectCondition, typename IteratorConnectHandler>
  446. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  447. iterator_connect_op<Protocol, SocketService, Iterator,
  448. ConnectCondition, IteratorConnectHandler>* this_handler)
  449. {
  450. asio_handler_alloc_helpers::deallocate(
  451. pointer, size, this_handler->handler_);
  452. }
  453. template <typename Protocol, typename SocketService, typename Iterator,
  454. typename ConnectCondition, typename IteratorConnectHandler>
  455. inline bool asio_handler_is_continuation(
  456. iterator_connect_op<Protocol, SocketService, Iterator,
  457. ConnectCondition, IteratorConnectHandler>* this_handler)
  458. {
  459. return asio_handler_cont_helpers::is_continuation(
  460. this_handler->handler_);
  461. }
  462. template <typename Function, typename Protocol,
  463. typename SocketService, typename Iterator,
  464. typename ConnectCondition, typename IteratorConnectHandler>
  465. inline void asio_handler_invoke(Function& function,
  466. iterator_connect_op<Protocol, SocketService, Iterator,
  467. ConnectCondition, IteratorConnectHandler>* this_handler)
  468. {
  469. asio_handler_invoke_helpers::invoke(
  470. function, this_handler->handler_);
  471. }
  472. template <typename Function, typename Protocol,
  473. typename SocketService, typename Iterator,
  474. typename ConnectCondition, typename IteratorConnectHandler>
  475. inline void asio_handler_invoke(const Function& function,
  476. iterator_connect_op<Protocol, SocketService, Iterator,
  477. ConnectCondition, IteratorConnectHandler>* this_handler)
  478. {
  479. asio_handler_invoke_helpers::invoke(
  480. function, this_handler->handler_);
  481. }
  482. } // namespace detail
  483. #if !defined(GENERATING_DOCUMENTATION)
  484. template <typename Protocol, typename SocketService,
  485. typename EndpointSequence, typename ConnectCondition,
  486. typename RangeConnectHandler, typename Allocator>
  487. struct associated_allocator<
  488. detail::range_connect_op<Protocol, SocketService,
  489. EndpointSequence, ConnectCondition, RangeConnectHandler>,
  490. Allocator>
  491. {
  492. typedef typename associated_allocator<
  493. RangeConnectHandler, Allocator>::type type;
  494. static type get(
  495. const detail::range_connect_op<Protocol, SocketService,
  496. EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
  497. const Allocator& a = Allocator()) ASIO_NOEXCEPT
  498. {
  499. return associated_allocator<RangeConnectHandler,
  500. Allocator>::get(h.handler_, a);
  501. }
  502. };
  503. template <typename Protocol, typename SocketService,
  504. typename EndpointSequence, typename ConnectCondition,
  505. typename RangeConnectHandler, typename Executor>
  506. struct associated_executor<
  507. detail::range_connect_op<Protocol, SocketService,
  508. EndpointSequence, ConnectCondition, RangeConnectHandler>,
  509. Executor>
  510. {
  511. typedef typename associated_executor<
  512. RangeConnectHandler, Executor>::type type;
  513. static type get(
  514. const detail::range_connect_op<Protocol, SocketService,
  515. EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
  516. const Executor& ex = Executor()) ASIO_NOEXCEPT
  517. {
  518. return associated_executor<RangeConnectHandler,
  519. Executor>::get(h.handler_, ex);
  520. }
  521. };
  522. template <typename Protocol, typename SocketService,
  523. typename Iterator, typename ConnectCondition,
  524. typename IteratorConnectHandler, typename Allocator>
  525. struct associated_allocator<
  526. detail::iterator_connect_op<Protocol, SocketService, Iterator,
  527. ConnectCondition, IteratorConnectHandler>,
  528. Allocator>
  529. {
  530. typedef typename associated_allocator<
  531. IteratorConnectHandler, Allocator>::type type;
  532. static type get(
  533. const detail::iterator_connect_op<Protocol, SocketService,
  534. Iterator, ConnectCondition, IteratorConnectHandler>& h,
  535. const Allocator& a = Allocator()) ASIO_NOEXCEPT
  536. {
  537. return associated_allocator<IteratorConnectHandler,
  538. Allocator>::get(h.handler_, a);
  539. }
  540. };
  541. template <typename Protocol, typename SocketService,
  542. typename Iterator, typename ConnectCondition,
  543. typename IteratorConnectHandler, typename Executor>
  544. struct associated_executor<
  545. detail::iterator_connect_op<Protocol, SocketService, Iterator,
  546. ConnectCondition, IteratorConnectHandler>,
  547. Executor>
  548. {
  549. typedef typename associated_executor<
  550. IteratorConnectHandler, Executor>::type type;
  551. static type get(
  552. const detail::iterator_connect_op<Protocol, SocketService,
  553. Iterator, ConnectCondition, IteratorConnectHandler>& h,
  554. const Executor& ex = Executor()) ASIO_NOEXCEPT
  555. {
  556. return associated_executor<IteratorConnectHandler,
  557. Executor>::get(h.handler_, ex);
  558. }
  559. };
  560. #endif // !defined(GENERATING_DOCUMENTATION)
  561. template <typename Protocol, typename SocketService,
  562. typename EndpointSequence, typename RangeConnectHandler>
  563. inline ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
  564. void (asio::error_code, typename Protocol::endpoint))
  565. async_connect(basic_socket<Protocol, SocketService>& s,
  566. const EndpointSequence& endpoints,
  567. ASIO_MOVE_ARG(RangeConnectHandler) handler,
  568. typename enable_if<is_endpoint_sequence<
  569. EndpointSequence>::value>::type*)
  570. {
  571. // If you get an error on the following line it means that your handler does
  572. // not meet the documented type requirements for a RangeConnectHandler.
  573. ASIO_RANGE_CONNECT_HANDLER_CHECK(
  574. RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
  575. async_completion<RangeConnectHandler,
  576. void (asio::error_code, typename Protocol::endpoint)>
  577. init(handler);
  578. detail::range_connect_op<Protocol, SocketService, EndpointSequence,
  579. detail::default_connect_condition,
  580. ASIO_HANDLER_TYPE(RangeConnectHandler,
  581. void (asio::error_code, typename Protocol::endpoint))>(s,
  582. endpoints, detail::default_connect_condition(), init.handler)(
  583. asio::error_code(), 1);
  584. return init.result.get();
  585. }
  586. #if !defined(ASIO_NO_DEPRECATED)
  587. template <typename Protocol, typename SocketService,
  588. typename Iterator, typename IteratorConnectHandler>
  589. inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
  590. void (asio::error_code, Iterator))
  591. async_connect(basic_socket<Protocol, SocketService>& s,
  592. Iterator begin, ASIO_MOVE_ARG(IteratorConnectHandler) handler,
  593. typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
  594. {
  595. // If you get an error on the following line it means that your handler does
  596. // not meet the documented type requirements for a IteratorConnectHandler.
  597. ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
  598. IteratorConnectHandler, handler, Iterator) type_check;
  599. async_completion<IteratorConnectHandler,
  600. void (asio::error_code, Iterator)> init(handler);
  601. detail::iterator_connect_op<Protocol, SocketService, Iterator,
  602. detail::default_connect_condition, ASIO_HANDLER_TYPE(
  603. IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
  604. begin, Iterator(), detail::default_connect_condition(), init.handler)(
  605. asio::error_code(), 1);
  606. return init.result.get();
  607. }
  608. #endif // !defined(ASIO_NO_DEPRECATED)
  609. template <typename Protocol, typename SocketService,
  610. typename Iterator, typename IteratorConnectHandler>
  611. inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
  612. void (asio::error_code, Iterator))
  613. async_connect(basic_socket<Protocol, SocketService>& s,
  614. Iterator begin, Iterator end,
  615. ASIO_MOVE_ARG(IteratorConnectHandler) handler)
  616. {
  617. // If you get an error on the following line it means that your handler does
  618. // not meet the documented type requirements for a IteratorConnectHandler.
  619. ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
  620. IteratorConnectHandler, handler, Iterator) type_check;
  621. async_completion<IteratorConnectHandler,
  622. void (asio::error_code, Iterator)> init(handler);
  623. detail::iterator_connect_op<Protocol, SocketService, Iterator,
  624. detail::default_connect_condition, ASIO_HANDLER_TYPE(
  625. IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
  626. begin, end, detail::default_connect_condition(), init.handler)(
  627. asio::error_code(), 1);
  628. return init.result.get();
  629. }
  630. template <typename Protocol, typename SocketService, typename EndpointSequence,
  631. typename ConnectCondition, typename RangeConnectHandler>
  632. inline ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
  633. void (asio::error_code, typename Protocol::endpoint))
  634. async_connect(basic_socket<Protocol, SocketService>& s,
  635. const EndpointSequence& endpoints, ConnectCondition connect_condition,
  636. ASIO_MOVE_ARG(RangeConnectHandler) handler,
  637. typename enable_if<is_endpoint_sequence<
  638. EndpointSequence>::value>::type*)
  639. {
  640. // If you get an error on the following line it means that your handler does
  641. // not meet the documented type requirements for a RangeConnectHandler.
  642. ASIO_RANGE_CONNECT_HANDLER_CHECK(
  643. RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
  644. async_completion<RangeConnectHandler,
  645. void (asio::error_code, typename Protocol::endpoint)>
  646. init(handler);
  647. detail::range_connect_op<Protocol, SocketService, EndpointSequence,
  648. ConnectCondition, ASIO_HANDLER_TYPE(RangeConnectHandler,
  649. void (asio::error_code, typename Protocol::endpoint))>(s,
  650. endpoints, connect_condition, init.handler)(
  651. asio::error_code(), 1);
  652. return init.result.get();
  653. }
  654. #if !defined(ASIO_NO_DEPRECATED)
  655. template <typename Protocol, typename SocketService, typename Iterator,
  656. typename ConnectCondition, typename IteratorConnectHandler>
  657. inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
  658. void (asio::error_code, Iterator))
  659. async_connect(basic_socket<Protocol, SocketService>& s,
  660. Iterator begin, ConnectCondition connect_condition,
  661. ASIO_MOVE_ARG(IteratorConnectHandler) handler,
  662. typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
  663. {
  664. // If you get an error on the following line it means that your handler does
  665. // not meet the documented type requirements for a IteratorConnectHandler.
  666. ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
  667. IteratorConnectHandler, handler, Iterator) type_check;
  668. async_completion<IteratorConnectHandler,
  669. void (asio::error_code, Iterator)> init(handler);
  670. detail::iterator_connect_op<Protocol, SocketService, Iterator,
  671. ConnectCondition, ASIO_HANDLER_TYPE(
  672. IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
  673. begin, Iterator(), connect_condition, init.handler)(
  674. asio::error_code(), 1);
  675. return init.result.get();
  676. }
  677. #endif // !defined(ASIO_NO_DEPRECATED)
  678. template <typename Protocol, typename SocketService, typename Iterator,
  679. typename ConnectCondition, typename IteratorConnectHandler>
  680. inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
  681. void (asio::error_code, Iterator))
  682. async_connect(basic_socket<Protocol, SocketService>& s,
  683. Iterator begin, Iterator end, ConnectCondition connect_condition,
  684. ASIO_MOVE_ARG(IteratorConnectHandler) handler)
  685. {
  686. // If you get an error on the following line it means that your handler does
  687. // not meet the documented type requirements for a IteratorConnectHandler.
  688. ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
  689. IteratorConnectHandler, handler, Iterator) type_check;
  690. async_completion<IteratorConnectHandler,
  691. void (asio::error_code, Iterator)> init(handler);
  692. detail::iterator_connect_op<Protocol, SocketService, Iterator,
  693. ConnectCondition, ASIO_HANDLER_TYPE(
  694. IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
  695. begin, end, connect_condition, init.handler)(
  696. asio::error_code(), 1);
  697. return init.result.get();
  698. }
  699. } // namespace asio
  700. #include "asio/detail/pop_options.hpp"
  701. #endif // ASIO_IMPL_CONNECT_HPP