]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/impl/connect.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / impl / connect.hpp
1 //
2 // impl/connect.hpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 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
11 #ifndef BOOST_ASIO_IMPL_CONNECT_HPP
12 #define BOOST_ASIO_IMPL_CONNECT_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <algorithm>
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>
29
30 #include <boost/asio/detail/push_options.hpp>
31
32 namespace boost {
33 namespace asio {
34
35 namespace detail
36 {
37 struct default_connect_condition
38 {
39 template <typename Endpoint>
40 bool operator()(const boost::system::error_code&, const Endpoint&)
41 {
42 return true;
43 }
44 };
45
46 template <typename Protocol, typename Iterator>
47 inline typename Protocol::endpoint deref_connect_result(
48 Iterator iter, boost::system::error_code& ec)
49 {
50 return ec ? typename Protocol::endpoint() : *iter;
51 }
52
53 template <typename T, typename Iterator>
54 struct legacy_connect_condition_helper : T
55 {
56 typedef char (*fallback_func_type)(...);
57 operator fallback_func_type() const;
58 };
59
60 template <typename R, typename Arg1, typename Arg2, typename Iterator>
61 struct legacy_connect_condition_helper<R (*)(Arg1, Arg2), Iterator>
62 {
63 R operator()(Arg1, Arg2) const;
64 char operator()(...) const;
65 };
66
67 template <typename T, typename Iterator>
68 struct is_legacy_connect_condition
69 {
70 static char asio_connect_condition_check(char);
71 static char (&asio_connect_condition_check(Iterator))[2];
72
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;
78 };
79
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)
85 {
86 if (next != end)
87 return connect_condition(ec, next);
88 return end;
89 }
90
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)
96 {
97 for (;next != end; ++next)
98 if (connect_condition(ec, *next))
99 return next;
100 return end;
101 }
102 }
103
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*)
110 {
111 boost::system::error_code ec;
112 typename Protocol::endpoint result = connect(s, endpoints, ec);
113 boost::asio::detail::throw_error(ec, "connect");
114 return result;
115 }
116
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*)
123 {
124 return detail::deref_connect_result<Protocol>(
125 connect(s, endpoints.begin(), endpoints.end(),
126 detail::default_connect_condition(), ec), ec);
127 }
128
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*)
133 {
134 boost::system::error_code ec;
135 Iterator result = connect(s, begin, ec);
136 boost::asio::detail::throw_error(ec, "connect");
137 return result;
138 }
139
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*)
144 {
145 return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);
146 }
147 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
148
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)
152 {
153 boost::system::error_code ec;
154 Iterator result = connect(s, begin, end, ec);
155 boost::asio::detail::throw_error(ec, "connect");
156 return result;
157 }
158
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)
162 {
163 return connect(s, begin, end, detail::default_connect_condition(), ec);
164 }
165
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*)
173 {
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");
178 return result;
179 }
180
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*)
189 {
190 return detail::deref_connect_result<Protocol>(
191 connect(s, endpoints.begin(), endpoints.end(),
192 connect_condition, ec), ec);
193 }
194
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*)
201 {
202 boost::system::error_code ec;
203 Iterator result = connect(s, begin, connect_condition, ec);
204 boost::asio::detail::throw_error(ec, "connect");
205 return result;
206 }
207
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*)
214 {
215 return connect(s, begin, Iterator(), connect_condition, ec);
216 }
217 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
218
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)
223 {
224 boost::system::error_code ec;
225 Iterator result = connect(s, begin, end, connect_condition, ec);
226 boost::asio::detail::throw_error(ec, "connect");
227 return result;
228 }
229
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)
235 {
236 ec = boost::system::error_code();
237
238 for (Iterator iter = begin; iter != end; ++iter)
239 {
240 iter = (detail::call_connect_condition(connect_condition, ec, iter, end));
241 if (iter != end)
242 {
243 s.close(ec);
244 s.connect(*iter, ec);
245 if (!ec)
246 return iter;
247 }
248 else
249 break;
250 }
251
252 if (!ec)
253 ec = boost::asio::error::not_found;
254
255 return end;
256 }
257
258 namespace detail
259 {
260 // Enable the empty base class optimisation for the connect condition.
261 template <typename ConnectCondition>
262 class base_from_connect_condition
263 {
264 protected:
265 explicit base_from_connect_condition(
266 const ConnectCondition& connect_condition)
267 : connect_condition_(connect_condition)
268 {
269 }
270
271 template <typename Iterator>
272 void check_condition(const boost::system::error_code& ec,
273 Iterator& iter, Iterator& end)
274 {
275 iter = detail::call_connect_condition(connect_condition_, ec, iter, end);
276 }
277
278 private:
279 ConnectCondition connect_condition_;
280 };
281
282 // The default_connect_condition implementation is essentially a no-op. This
283 // template specialisation lets us eliminate all costs associated with it.
284 template <>
285 class base_from_connect_condition<default_connect_condition>
286 {
287 protected:
288 explicit base_from_connect_condition(const default_connect_condition&)
289 {
290 }
291
292 template <typename Iterator>
293 void check_condition(const boost::system::error_code&, Iterator&, Iterator&)
294 {
295 }
296 };
297
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>
302 {
303 public:
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),
309 socket_(sock),
310 endpoints_(endpoints),
311 index_(0),
312 start_(0),
313 handler_(BOOST_ASIO_MOVE_CAST(RangeConnectHandler)(handler))
314 {
315 }
316
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_)
325 {
326 }
327
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_))
335 {
336 }
337 #endif // defined(BOOST_ASIO_HAS_MOVE)
338
339 void operator()(boost::system::error_code ec, int start = 0)
340 {
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();
345
346 switch (start_ = start)
347 {
348 case 1:
349 for (;;)
350 {
351 this->check_condition(ec, iter, end);
352 index_ = std::distance(begin, iter);
353
354 if (iter != end)
355 {
356 socket_.close(ec);
357 socket_.async_connect(*iter,
358 BOOST_ASIO_MOVE_CAST(range_connect_op)(*this));
359 return;
360 }
361
362 if (start)
363 {
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));
368 return;
369 }
370
371 default:
372
373 if (iter == end)
374 break;
375
376 if (!socket_.is_open())
377 {
378 ec = boost::asio::error::operation_aborted;
379 break;
380 }
381
382 if (!ec)
383 break;
384
385 ++iter;
386 ++index_;
387 }
388
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));
392 }
393 }
394
395 //private:
396 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket_;
397 EndpointSequence endpoints_;
398 std::size_t index_;
399 int start_;
400 RangeConnectHandler handler_;
401 };
402
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)
409 {
410 return boost_asio_handler_alloc_helpers::allocate(
411 size, this_handler->handler_);
412 }
413
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)
420 {
421 boost_asio_handler_alloc_helpers::deallocate(
422 pointer, size, this_handler->handler_);
423 }
424
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)
431 {
432 return boost_asio_handler_cont_helpers::is_continuation(
433 this_handler->handler_);
434 }
435
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)
442 {
443 boost_asio_handler_invoke_helpers::invoke(
444 function, this_handler->handler_);
445 }
446
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)
453 {
454 boost_asio_handler_invoke_helpers::invoke(
455 function, this_handler->handler_);
456 }
457
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>
461 {
462 public:
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),
468 socket_(sock),
469 iter_(begin),
470 end_(end),
471 start_(0),
472 handler_(BOOST_ASIO_MOVE_CAST(IteratorConnectHandler)(handler))
473 {
474 }
475
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_),
480 iter_(other.iter_),
481 end_(other.end_),
482 start_(other.start_),
483 handler_(other.handler_)
484 {
485 }
486
487 iterator_connect_op(iterator_connect_op&& other)
488 : base_from_connect_condition<ConnectCondition>(other),
489 socket_(other.socket_),
490 iter_(other.iter_),
491 end_(other.end_),
492 start_(other.start_),
493 handler_(BOOST_ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_))
494 {
495 }
496 #endif // defined(BOOST_ASIO_HAS_MOVE)
497
498 void operator()(boost::system::error_code ec, int start = 0)
499 {
500 switch (start_ = start)
501 {
502 case 1:
503 for (;;)
504 {
505 this->check_condition(ec, iter_, end_);
506
507 if (iter_ != end_)
508 {
509 socket_.close(ec);
510 socket_.async_connect(*iter_,
511 BOOST_ASIO_MOVE_CAST(iterator_connect_op)(*this));
512 return;
513 }
514
515 if (start)
516 {
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));
521 return;
522 }
523
524 default:
525
526 if (iter_ == end_)
527 break;
528
529 if (!socket_.is_open())
530 {
531 ec = boost::asio::error::operation_aborted;
532 break;
533 }
534
535 if (!ec)
536 break;
537
538 ++iter_;
539 }
540
541 handler_(static_cast<const boost::system::error_code&>(ec),
542 static_cast<const Iterator&>(iter_));
543 }
544 }
545
546 //private:
547 basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket_;
548 Iterator iter_;
549 Iterator end_;
550 int start_;
551 IteratorConnectHandler handler_;
552 };
553
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)
559 {
560 return boost_asio_handler_alloc_helpers::allocate(
561 size, this_handler->handler_);
562 }
563
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)
569 {
570 boost_asio_handler_alloc_helpers::deallocate(
571 pointer, size, this_handler->handler_);
572 }
573
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)
579 {
580 return boost_asio_handler_cont_helpers::is_continuation(
581 this_handler->handler_);
582 }
583
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)
590 {
591 boost_asio_handler_invoke_helpers::invoke(
592 function, this_handler->handler_);
593 }
594
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)
601 {
602 boost_asio_handler_invoke_helpers::invoke(
603 function, this_handler->handler_);
604 }
605 } // namespace detail
606
607 #if !defined(GENERATING_DOCUMENTATION)
608
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>,
615 Allocator>
616 {
617 typedef typename associated_allocator<
618 RangeConnectHandler, Allocator>::type type;
619
620 static type get(
621 const detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
622 EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
623 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
624 {
625 return associated_allocator<RangeConnectHandler,
626 Allocator>::get(h.handler_, a);
627 }
628 };
629
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>,
636 Executor>
637 {
638 typedef typename associated_executor<
639 RangeConnectHandler, Executor>::type type;
640
641 static type get(
642 const detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
643 EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
644 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
645 {
646 return associated_executor<RangeConnectHandler,
647 Executor>::get(h.handler_, ex);
648 }
649 };
650
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>,
657 Allocator>
658 {
659 typedef typename associated_allocator<
660 IteratorConnectHandler, Allocator>::type type;
661
662 static type get(
663 const detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG,
664 Iterator, ConnectCondition, IteratorConnectHandler>& h,
665 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
666 {
667 return associated_allocator<IteratorConnectHandler,
668 Allocator>::get(h.handler_, a);
669 }
670 };
671
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>,
678 Executor>
679 {
680 typedef typename associated_executor<
681 IteratorConnectHandler, Executor>::type type;
682
683 static type get(
684 const detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG,
685 Iterator, ConnectCondition, IteratorConnectHandler>& h,
686 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
687 {
688 return associated_executor<IteratorConnectHandler,
689 Executor>::get(h.handler_, ex);
690 }
691 };
692
693 #endif // !defined(GENERATING_DOCUMENTATION)
694
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*)
704 {
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;
709
710 async_completion<RangeConnectHandler,
711 void (boost::system::error_code, typename Protocol::endpoint)>
712 init(handler);
713
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);
720
721 return init.result.get();
722 }
723
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*)
732 {
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;
737
738 async_completion<IteratorConnectHandler,
739 void (boost::system::error_code, Iterator)> init(handler);
740
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);
746
747 return init.result.get();
748 }
749 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
750
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)
758 {
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;
763
764 async_completion<IteratorConnectHandler,
765 void (boost::system::error_code, Iterator)> init(handler);
766
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);
772
773 return init.result.get();
774 }
775
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*)
785 {
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;
790
791 async_completion<RangeConnectHandler,
792 void (boost::system::error_code, typename Protocol::endpoint)>
793 init(handler);
794
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);
800
801 return init.result.get();
802 }
803
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*)
813 {
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;
818
819 async_completion<IteratorConnectHandler,
820 void (boost::system::error_code, Iterator)> init(handler);
821
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);
827
828 return init.result.get();
829 }
830 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
831
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)
839 {
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;
844
845 async_completion<IteratorConnectHandler,
846 void (boost::system::error_code, Iterator)> init(handler);
847
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);
853
854 return init.result.get();
855 }
856
857 } // namespace asio
858 } // namespace boost
859
860 #include <boost/asio/detail/pop_options.hpp>
861
862 #endif // BOOST_ASIO_IMPL_CONNECT_HPP