PageRenderTime 55ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/ThirdParty/ASIO/include/asio/impl/connect.hpp

https://gitlab.com/Teo-Mirror/AtomicGameEngine
C++ Header | 428 lines | 348 code | 59 blank | 21 comment | 18 complexity | ed7361c68092cd560ee7f1343fbe0d99 MD5 | raw file
  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 "asio/detail/bind_handler.hpp"
  16. #include "asio/detail/consuming_buffers.hpp"
  17. #include "asio/detail/handler_alloc_helpers.hpp"
  18. #include "asio/detail/handler_cont_helpers.hpp"
  19. #include "asio/detail/handler_invoke_helpers.hpp"
  20. #include "asio/detail/handler_type_requirements.hpp"
  21. #include "asio/detail/throw_error.hpp"
  22. #include "asio/error.hpp"
  23. #include "asio/detail/push_options.hpp"
  24. namespace asio {
  25. namespace detail
  26. {
  27. struct default_connect_condition
  28. {
  29. template <typename Iterator>
  30. Iterator operator()(const asio::error_code&, Iterator next)
  31. {
  32. return next;
  33. }
  34. };
  35. }
  36. template <typename Protocol, typename SocketService, typename Iterator>
  37. Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin)
  38. {
  39. asio::error_code ec;
  40. Iterator result = connect(s, begin, ec);
  41. asio::detail::throw_error(ec, "connect");
  42. return result;
  43. }
  44. template <typename Protocol, typename SocketService, typename Iterator>
  45. inline Iterator connect(basic_socket<Protocol, SocketService>& s,
  46. Iterator begin, asio::error_code& ec)
  47. {
  48. return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);
  49. }
  50. template <typename Protocol, typename SocketService, typename Iterator>
  51. Iterator connect(basic_socket<Protocol, SocketService>& s,
  52. Iterator begin, Iterator end)
  53. {
  54. asio::error_code ec;
  55. Iterator result = connect(s, begin, end, ec);
  56. asio::detail::throw_error(ec, "connect");
  57. return result;
  58. }
  59. template <typename Protocol, typename SocketService, typename Iterator>
  60. inline Iterator connect(basic_socket<Protocol, SocketService>& s,
  61. Iterator begin, Iterator end, asio::error_code& ec)
  62. {
  63. return connect(s, begin, end, detail::default_connect_condition(), ec);
  64. }
  65. template <typename Protocol, typename SocketService,
  66. typename Iterator, typename ConnectCondition>
  67. Iterator connect(basic_socket<Protocol, SocketService>& s,
  68. Iterator begin, ConnectCondition connect_condition)
  69. {
  70. asio::error_code ec;
  71. Iterator result = connect(s, begin, connect_condition, ec);
  72. asio::detail::throw_error(ec, "connect");
  73. return result;
  74. }
  75. template <typename Protocol, typename SocketService,
  76. typename Iterator, typename ConnectCondition>
  77. inline Iterator connect(basic_socket<Protocol, SocketService>& s,
  78. Iterator begin, ConnectCondition connect_condition,
  79. asio::error_code& ec)
  80. {
  81. return connect(s, begin, Iterator(), connect_condition, ec);
  82. }
  83. template <typename Protocol, typename SocketService,
  84. typename Iterator, typename ConnectCondition>
  85. Iterator connect(basic_socket<Protocol, SocketService>& s,
  86. Iterator begin, Iterator end, ConnectCondition connect_condition)
  87. {
  88. asio::error_code ec;
  89. Iterator result = connect(s, begin, end, connect_condition, ec);
  90. asio::detail::throw_error(ec, "connect");
  91. return result;
  92. }
  93. template <typename Protocol, typename SocketService,
  94. typename Iterator, typename ConnectCondition>
  95. Iterator connect(basic_socket<Protocol, SocketService>& s,
  96. Iterator begin, Iterator end, ConnectCondition connect_condition,
  97. asio::error_code& ec)
  98. {
  99. ec = asio::error_code();
  100. for (Iterator iter = begin; iter != end; ++iter)
  101. {
  102. iter = connect_condition(ec, iter);
  103. if (iter != end)
  104. {
  105. s.close(ec);
  106. s.connect(*iter, ec);
  107. if (!ec)
  108. return iter;
  109. }
  110. }
  111. if (!ec)
  112. ec = asio::error::not_found;
  113. return end;
  114. }
  115. namespace detail
  116. {
  117. // Enable the empty base class optimisation for the connect condition.
  118. template <typename ConnectCondition>
  119. class base_from_connect_condition
  120. {
  121. protected:
  122. explicit base_from_connect_condition(
  123. const ConnectCondition& connect_condition)
  124. : connect_condition_(connect_condition)
  125. {
  126. }
  127. template <typename Iterator>
  128. void check_condition(const asio::error_code& ec,
  129. Iterator& iter, Iterator& end)
  130. {
  131. if (iter != end)
  132. iter = connect_condition_(ec, static_cast<const Iterator&>(iter));
  133. }
  134. private:
  135. ConnectCondition connect_condition_;
  136. };
  137. // The default_connect_condition implementation is essentially a no-op. This
  138. // template specialisation lets us eliminate all costs associated with it.
  139. template <>
  140. class base_from_connect_condition<default_connect_condition>
  141. {
  142. protected:
  143. explicit base_from_connect_condition(const default_connect_condition&)
  144. {
  145. }
  146. template <typename Iterator>
  147. void check_condition(const asio::error_code&, Iterator&, Iterator&)
  148. {
  149. }
  150. };
  151. template <typename Protocol, typename SocketService, typename Iterator,
  152. typename ConnectCondition, typename ComposedConnectHandler>
  153. class connect_op : base_from_connect_condition<ConnectCondition>
  154. {
  155. public:
  156. connect_op(basic_socket<Protocol, SocketService>& sock,
  157. const Iterator& begin, const Iterator& end,
  158. const ConnectCondition& connect_condition,
  159. ComposedConnectHandler& handler)
  160. : base_from_connect_condition<ConnectCondition>(connect_condition),
  161. socket_(sock),
  162. iter_(begin),
  163. end_(end),
  164. start_(0),
  165. handler_(ASIO_MOVE_CAST(ComposedConnectHandler)(handler))
  166. {
  167. }
  168. #if defined(ASIO_HAS_MOVE)
  169. connect_op(const connect_op& other)
  170. : base_from_connect_condition<ConnectCondition>(other),
  171. socket_(other.socket_),
  172. iter_(other.iter_),
  173. end_(other.end_),
  174. start_(other.start_),
  175. handler_(other.handler_)
  176. {
  177. }
  178. connect_op(connect_op&& other)
  179. : base_from_connect_condition<ConnectCondition>(other),
  180. socket_(other.socket_),
  181. iter_(other.iter_),
  182. end_(other.end_),
  183. start_(other.start_),
  184. handler_(ASIO_MOVE_CAST(ComposedConnectHandler)(other.handler_))
  185. {
  186. }
  187. #endif // defined(ASIO_HAS_MOVE)
  188. void operator()(asio::error_code ec, int start = 0)
  189. {
  190. switch (start_ = start)
  191. {
  192. case 1:
  193. for (;;)
  194. {
  195. this->check_condition(ec, iter_, end_);
  196. if (iter_ != end_)
  197. {
  198. socket_.close(ec);
  199. socket_.async_connect(*iter_,
  200. ASIO_MOVE_CAST(connect_op)(*this));
  201. return;
  202. }
  203. if (start)
  204. {
  205. ec = asio::error::not_found;
  206. socket_.get_io_service().post(detail::bind_handler(*this, ec));
  207. return;
  208. }
  209. default:
  210. if (iter_ == end_)
  211. break;
  212. if (!socket_.is_open())
  213. {
  214. ec = asio::error::operation_aborted;
  215. break;
  216. }
  217. if (!ec)
  218. break;
  219. ++iter_;
  220. }
  221. handler_(static_cast<const asio::error_code&>(ec),
  222. static_cast<const Iterator&>(iter_));
  223. }
  224. }
  225. //private:
  226. basic_socket<Protocol, SocketService>& socket_;
  227. Iterator iter_;
  228. Iterator end_;
  229. int start_;
  230. ComposedConnectHandler handler_;
  231. };
  232. template <typename Protocol, typename SocketService, typename Iterator,
  233. typename ConnectCondition, typename ComposedConnectHandler>
  234. inline void* asio_handler_allocate(std::size_t size,
  235. connect_op<Protocol, SocketService, Iterator,
  236. ConnectCondition, ComposedConnectHandler>* this_handler)
  237. {
  238. return asio_handler_alloc_helpers::allocate(
  239. size, this_handler->handler_);
  240. }
  241. template <typename Protocol, typename SocketService, typename Iterator,
  242. typename ConnectCondition, typename ComposedConnectHandler>
  243. inline void asio_handler_deallocate(void* pointer, std::size_t size,
  244. connect_op<Protocol, SocketService, Iterator,
  245. ConnectCondition, ComposedConnectHandler>* this_handler)
  246. {
  247. asio_handler_alloc_helpers::deallocate(
  248. pointer, size, this_handler->handler_);
  249. }
  250. template <typename Protocol, typename SocketService, typename Iterator,
  251. typename ConnectCondition, typename ComposedConnectHandler>
  252. inline bool asio_handler_is_continuation(
  253. connect_op<Protocol, SocketService, Iterator,
  254. ConnectCondition, ComposedConnectHandler>* this_handler)
  255. {
  256. return asio_handler_cont_helpers::is_continuation(
  257. this_handler->handler_);
  258. }
  259. template <typename Function, typename Protocol,
  260. typename SocketService, typename Iterator,
  261. typename ConnectCondition, typename ComposedConnectHandler>
  262. inline void asio_handler_invoke(Function& function,
  263. connect_op<Protocol, SocketService, Iterator,
  264. ConnectCondition, ComposedConnectHandler>* this_handler)
  265. {
  266. asio_handler_invoke_helpers::invoke(
  267. function, this_handler->handler_);
  268. }
  269. template <typename Function, typename Protocol,
  270. typename SocketService, typename Iterator,
  271. typename ConnectCondition, typename ComposedConnectHandler>
  272. inline void asio_handler_invoke(const Function& function,
  273. connect_op<Protocol, SocketService, Iterator,
  274. ConnectCondition, ComposedConnectHandler>* this_handler)
  275. {
  276. asio_handler_invoke_helpers::invoke(
  277. function, this_handler->handler_);
  278. }
  279. } // namespace detail
  280. template <typename Protocol, typename SocketService,
  281. typename Iterator, typename ComposedConnectHandler>
  282. inline ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
  283. void (asio::error_code, Iterator))
  284. async_connect(basic_socket<Protocol, SocketService>& s,
  285. Iterator begin, ASIO_MOVE_ARG(ComposedConnectHandler) handler)
  286. {
  287. // If you get an error on the following line it means that your handler does
  288. // not meet the documented type requirements for a ComposedConnectHandler.
  289. ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
  290. ComposedConnectHandler, handler, Iterator) type_check;
  291. detail::async_result_init<ComposedConnectHandler,
  292. void (asio::error_code, Iterator)> init(
  293. ASIO_MOVE_CAST(ComposedConnectHandler)(handler));
  294. detail::connect_op<Protocol, SocketService, Iterator,
  295. detail::default_connect_condition, ASIO_HANDLER_TYPE(
  296. ComposedConnectHandler, void (asio::error_code, Iterator))>(s,
  297. begin, Iterator(), detail::default_connect_condition(), init.handler)(
  298. asio::error_code(), 1);
  299. return init.result.get();
  300. }
  301. template <typename Protocol, typename SocketService,
  302. typename Iterator, typename ComposedConnectHandler>
  303. inline ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
  304. void (asio::error_code, Iterator))
  305. async_connect(basic_socket<Protocol, SocketService>& s,
  306. Iterator begin, Iterator end,
  307. ASIO_MOVE_ARG(ComposedConnectHandler) handler)
  308. {
  309. // If you get an error on the following line it means that your handler does
  310. // not meet the documented type requirements for a ComposedConnectHandler.
  311. ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
  312. ComposedConnectHandler, handler, Iterator) type_check;
  313. detail::async_result_init<ComposedConnectHandler,
  314. void (asio::error_code, Iterator)> init(
  315. ASIO_MOVE_CAST(ComposedConnectHandler)(handler));
  316. detail::connect_op<Protocol, SocketService, Iterator,
  317. detail::default_connect_condition, ASIO_HANDLER_TYPE(
  318. ComposedConnectHandler, void (asio::error_code, Iterator))>(s,
  319. begin, end, detail::default_connect_condition(), init.handler)(
  320. asio::error_code(), 1);
  321. return init.result.get();
  322. }
  323. template <typename Protocol, typename SocketService, typename Iterator,
  324. typename ConnectCondition, typename ComposedConnectHandler>
  325. inline ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
  326. void (asio::error_code, Iterator))
  327. async_connect(basic_socket<Protocol, SocketService>& s,
  328. Iterator begin, ConnectCondition connect_condition,
  329. ASIO_MOVE_ARG(ComposedConnectHandler) handler)
  330. {
  331. // If you get an error on the following line it means that your handler does
  332. // not meet the documented type requirements for a ComposedConnectHandler.
  333. ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
  334. ComposedConnectHandler, handler, Iterator) type_check;
  335. detail::async_result_init<ComposedConnectHandler,
  336. void (asio::error_code, Iterator)> init(
  337. ASIO_MOVE_CAST(ComposedConnectHandler)(handler));
  338. detail::connect_op<Protocol, SocketService, Iterator,
  339. ConnectCondition, ASIO_HANDLER_TYPE(
  340. ComposedConnectHandler, void (asio::error_code, Iterator))>(s,
  341. begin, Iterator(), connect_condition, init.handler)(
  342. asio::error_code(), 1);
  343. return init.result.get();
  344. }
  345. template <typename Protocol, typename SocketService, typename Iterator,
  346. typename ConnectCondition, typename ComposedConnectHandler>
  347. inline ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
  348. void (asio::error_code, Iterator))
  349. async_connect(basic_socket<Protocol, SocketService>& s,
  350. Iterator begin, Iterator end, ConnectCondition connect_condition,
  351. ASIO_MOVE_ARG(ComposedConnectHandler) handler)
  352. {
  353. // If you get an error on the following line it means that your handler does
  354. // not meet the documented type requirements for a ComposedConnectHandler.
  355. ASIO_COMPOSED_CONNECT_HANDLER_CHECK(
  356. ComposedConnectHandler, handler, Iterator) type_check;
  357. detail::async_result_init<ComposedConnectHandler,
  358. void (asio::error_code, Iterator)> init(
  359. ASIO_MOVE_CAST(ComposedConnectHandler)(handler));
  360. detail::connect_op<Protocol, SocketService, Iterator,
  361. ConnectCondition, ASIO_HANDLER_TYPE(
  362. ComposedConnectHandler, void (asio::error_code, Iterator))>(s,
  363. begin, end, connect_condition, init.handler)(
  364. asio::error_code(), 1);
  365. return init.result.get();
  366. }
  367. } // namespace asio
  368. #include "asio/detail/pop_options.hpp"
  369. #endif // ASIO_IMPL_CONNECT_HPP