]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/impl/connect.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / asio / impl / connect.hpp
1 //
2 // impl/connect.hpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 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/non_const_lvalue.hpp>
27 #include <boost/asio/detail/throw_error.hpp>
28 #include <boost/asio/error.hpp>
29 #include <boost/asio/post.hpp>
30
31 #include <boost/asio/detail/push_options.hpp>
32
33 namespace boost {
34 namespace asio {
35
36 namespace detail
37 {
38 struct default_connect_condition
39 {
40 template <typename Endpoint>
41 bool operator()(const boost::system::error_code&, const Endpoint&)
42 {
43 return true;
44 }
45 };
46
47 template <typename Protocol, typename Iterator>
48 inline typename Protocol::endpoint deref_connect_result(
49 Iterator iter, boost::system::error_code& ec)
50 {
51 return ec ? typename Protocol::endpoint() : *iter;
52 }
53
54 template <typename T, typename Iterator>
55 struct legacy_connect_condition_helper : T
56 {
57 typedef char (*fallback_func_type)(...);
58 operator fallback_func_type() const;
59 };
60
61 template <typename R, typename Arg1, typename Arg2, typename Iterator>
62 struct legacy_connect_condition_helper<R (*)(Arg1, Arg2), Iterator>
63 {
64 R operator()(Arg1, Arg2) const;
65 char operator()(...) const;
66 };
67
68 template <typename T, typename Iterator>
69 struct is_legacy_connect_condition
70 {
71 static char asio_connect_condition_check(char);
72 static char (&asio_connect_condition_check(Iterator))[2];
73
74 static const bool value =
75 sizeof(asio_connect_condition_check(
76 (*static_cast<legacy_connect_condition_helper<T, Iterator>*>(0))(
77 *static_cast<const boost::system::error_code*>(0),
78 *static_cast<const Iterator*>(0)))) != 1;
79 };
80
81 template <typename ConnectCondition, typename Iterator>
82 inline Iterator call_connect_condition(ConnectCondition& connect_condition,
83 const boost::system::error_code& ec, Iterator next, Iterator end,
84 typename enable_if<is_legacy_connect_condition<
85 ConnectCondition, Iterator>::value>::type* = 0)
86 {
87 if (next != end)
88 return connect_condition(ec, next);
89 return end;
90 }
91
92 template <typename ConnectCondition, typename Iterator>
93 inline Iterator call_connect_condition(ConnectCondition& connect_condition,
94 const boost::system::error_code& ec, Iterator next, Iterator end,
95 typename enable_if<!is_legacy_connect_condition<
96 ConnectCondition, Iterator>::value>::type* = 0)
97 {
98 for (;next != end; ++next)
99 if (connect_condition(ec, *next))
100 return next;
101 return end;
102 }
103 }
104
105 template <typename Protocol, typename Executor, typename EndpointSequence>
106 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& 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, typename Executor, typename EndpointSequence>
118 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
119 const EndpointSequence& endpoints, boost::system::error_code& ec,
120 typename enable_if<is_endpoint_sequence<
121 EndpointSequence>::value>::type*)
122 {
123 return detail::deref_connect_result<Protocol>(
124 connect(s, endpoints.begin(), endpoints.end(),
125 detail::default_connect_condition(), ec), ec);
126 }
127
128 #if !defined(BOOST_ASIO_NO_DEPRECATED)
129 template <typename Protocol, typename Executor, typename Iterator>
130 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
131 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
132 {
133 boost::system::error_code ec;
134 Iterator result = connect(s, begin, ec);
135 boost::asio::detail::throw_error(ec, "connect");
136 return result;
137 }
138
139 template <typename Protocol, typename Executor, typename Iterator>
140 inline Iterator connect(basic_socket<Protocol, Executor>& s,
141 Iterator begin, boost::system::error_code& ec,
142 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
143 {
144 return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);
145 }
146 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
147
148 template <typename Protocol, typename Executor, typename Iterator>
149 Iterator connect(basic_socket<Protocol, Executor>& s,
150 Iterator begin, Iterator end)
151 {
152 boost::system::error_code ec;
153 Iterator result = connect(s, begin, end, ec);
154 boost::asio::detail::throw_error(ec, "connect");
155 return result;
156 }
157
158 template <typename Protocol, typename Executor, typename Iterator>
159 inline Iterator connect(basic_socket<Protocol, Executor>& s,
160 Iterator begin, Iterator end, boost::system::error_code& ec)
161 {
162 return connect(s, begin, end, detail::default_connect_condition(), ec);
163 }
164
165 template <typename Protocol, typename Executor,
166 typename EndpointSequence, typename ConnectCondition>
167 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
168 const EndpointSequence& endpoints, ConnectCondition connect_condition,
169 typename enable_if<is_endpoint_sequence<
170 EndpointSequence>::value>::type*)
171 {
172 boost::system::error_code ec;
173 typename Protocol::endpoint result = connect(
174 s, endpoints, connect_condition, ec);
175 boost::asio::detail::throw_error(ec, "connect");
176 return result;
177 }
178
179 template <typename Protocol, typename Executor,
180 typename EndpointSequence, typename ConnectCondition>
181 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
182 const EndpointSequence& endpoints, ConnectCondition connect_condition,
183 boost::system::error_code& ec,
184 typename enable_if<is_endpoint_sequence<
185 EndpointSequence>::value>::type*)
186 {
187 return detail::deref_connect_result<Protocol>(
188 connect(s, endpoints.begin(), endpoints.end(),
189 connect_condition, ec), ec);
190 }
191
192 #if !defined(BOOST_ASIO_NO_DEPRECATED)
193 template <typename Protocol, typename Executor,
194 typename Iterator, typename ConnectCondition>
195 Iterator connect(basic_socket<Protocol, Executor>& s,
196 Iterator begin, ConnectCondition connect_condition,
197 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
198 {
199 boost::system::error_code ec;
200 Iterator result = connect(s, begin, connect_condition, ec);
201 boost::asio::detail::throw_error(ec, "connect");
202 return result;
203 }
204
205 template <typename Protocol, typename Executor,
206 typename Iterator, typename ConnectCondition>
207 inline Iterator connect(basic_socket<Protocol, Executor>& s,
208 Iterator begin, ConnectCondition connect_condition,
209 boost::system::error_code& ec,
210 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
211 {
212 return connect(s, begin, Iterator(), connect_condition, ec);
213 }
214 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
215
216 template <typename Protocol, typename Executor,
217 typename Iterator, typename ConnectCondition>
218 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
219 Iterator end, ConnectCondition connect_condition)
220 {
221 boost::system::error_code ec;
222 Iterator result = connect(s, begin, end, connect_condition, ec);
223 boost::asio::detail::throw_error(ec, "connect");
224 return result;
225 }
226
227 template <typename Protocol, typename Executor,
228 typename Iterator, typename ConnectCondition>
229 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
230 Iterator end, ConnectCondition connect_condition,
231 boost::system::error_code& ec)
232 {
233 ec = boost::system::error_code();
234
235 for (Iterator iter = begin; iter != end; ++iter)
236 {
237 iter = (detail::call_connect_condition(connect_condition, ec, iter, end));
238 if (iter != end)
239 {
240 s.close(ec);
241 s.connect(*iter, ec);
242 if (!ec)
243 return iter;
244 }
245 else
246 break;
247 }
248
249 if (!ec)
250 ec = boost::asio::error::not_found;
251
252 return end;
253 }
254
255 namespace detail
256 {
257 // Enable the empty base class optimisation for the connect condition.
258 template <typename ConnectCondition>
259 class base_from_connect_condition
260 {
261 protected:
262 explicit base_from_connect_condition(
263 const ConnectCondition& connect_condition)
264 : connect_condition_(connect_condition)
265 {
266 }
267
268 template <typename Iterator>
269 void check_condition(const boost::system::error_code& ec,
270 Iterator& iter, Iterator& end)
271 {
272 iter = detail::call_connect_condition(connect_condition_, ec, iter, end);
273 }
274
275 private:
276 ConnectCondition connect_condition_;
277 };
278
279 // The default_connect_condition implementation is essentially a no-op. This
280 // template specialisation lets us eliminate all costs associated with it.
281 template <>
282 class base_from_connect_condition<default_connect_condition>
283 {
284 protected:
285 explicit base_from_connect_condition(const default_connect_condition&)
286 {
287 }
288
289 template <typename Iterator>
290 void check_condition(const boost::system::error_code&, Iterator&, Iterator&)
291 {
292 }
293 };
294
295 template <typename Protocol, typename Executor, typename EndpointSequence,
296 typename ConnectCondition, typename RangeConnectHandler>
297 class range_connect_op : base_from_connect_condition<ConnectCondition>
298 {
299 public:
300 range_connect_op(basic_socket<Protocol, Executor>& sock,
301 const EndpointSequence& endpoints,
302 const ConnectCondition& connect_condition,
303 RangeConnectHandler& handler)
304 : base_from_connect_condition<ConnectCondition>(connect_condition),
305 socket_(sock),
306 endpoints_(endpoints),
307 index_(0),
308 start_(0),
309 handler_(BOOST_ASIO_MOVE_CAST(RangeConnectHandler)(handler))
310 {
311 }
312
313 #if defined(BOOST_ASIO_HAS_MOVE)
314 range_connect_op(const range_connect_op& other)
315 : base_from_connect_condition<ConnectCondition>(other),
316 socket_(other.socket_),
317 endpoints_(other.endpoints_),
318 index_(other.index_),
319 start_(other.start_),
320 handler_(other.handler_)
321 {
322 }
323
324 range_connect_op(range_connect_op&& other)
325 : base_from_connect_condition<ConnectCondition>(other),
326 socket_(other.socket_),
327 endpoints_(other.endpoints_),
328 index_(other.index_),
329 start_(other.start_),
330 handler_(BOOST_ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_))
331 {
332 }
333 #endif // defined(BOOST_ASIO_HAS_MOVE)
334
335 void operator()(boost::system::error_code ec, int start = 0)
336 {
337 this->process(ec, start,
338 const_cast<const EndpointSequence&>(endpoints_).begin(),
339 const_cast<const EndpointSequence&>(endpoints_).end());
340 }
341
342 //private:
343 template <typename Iterator>
344 void process(boost::system::error_code ec,
345 int start, Iterator begin, Iterator end)
346 {
347 Iterator iter = begin;
348 std::advance(iter, index_);
349
350 switch (start_ = start)
351 {
352 case 1:
353 for (;;)
354 {
355 this->check_condition(ec, iter, end);
356 index_ = std::distance(begin, iter);
357
358 if (iter != end)
359 {
360 socket_.close(ec);
361 socket_.async_connect(*iter,
362 BOOST_ASIO_MOVE_CAST(range_connect_op)(*this));
363 return;
364 }
365
366 if (start)
367 {
368 ec = boost::asio::error::not_found;
369 boost::asio::post(socket_.get_executor(),
370 detail::bind_handler(
371 BOOST_ASIO_MOVE_CAST(range_connect_op)(*this), ec));
372 return;
373 }
374
375 /* fall-through */ default:
376
377 if (iter == end)
378 break;
379
380 if (!socket_.is_open())
381 {
382 ec = boost::asio::error::operation_aborted;
383 break;
384 }
385
386 if (!ec)
387 break;
388
389 ++iter;
390 ++index_;
391 }
392
393 handler_(static_cast<const boost::system::error_code&>(ec),
394 static_cast<const typename Protocol::endpoint&>(
395 ec || iter == end ? typename Protocol::endpoint() : *iter));
396 }
397 }
398
399 basic_socket<Protocol, Executor>& socket_;
400 EndpointSequence endpoints_;
401 std::size_t index_;
402 int start_;
403 RangeConnectHandler handler_;
404 };
405
406 template <typename Protocol, typename Executor, typename EndpointSequence,
407 typename ConnectCondition, typename RangeConnectHandler>
408 inline void* asio_handler_allocate(std::size_t size,
409 range_connect_op<Protocol, Executor, EndpointSequence,
410 ConnectCondition, RangeConnectHandler>* this_handler)
411 {
412 return boost_asio_handler_alloc_helpers::allocate(
413 size, this_handler->handler_);
414 }
415
416 template <typename Protocol, typename Executor, typename EndpointSequence,
417 typename ConnectCondition, typename RangeConnectHandler>
418 inline void asio_handler_deallocate(void* pointer, std::size_t size,
419 range_connect_op<Protocol, Executor, EndpointSequence,
420 ConnectCondition, RangeConnectHandler>* this_handler)
421 {
422 boost_asio_handler_alloc_helpers::deallocate(
423 pointer, size, this_handler->handler_);
424 }
425
426 template <typename Protocol, typename Executor, typename EndpointSequence,
427 typename ConnectCondition, typename RangeConnectHandler>
428 inline bool asio_handler_is_continuation(
429 range_connect_op<Protocol, Executor, 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 Executor, typename Protocol,
437 typename EndpointSequence, typename ConnectCondition,
438 typename RangeConnectHandler>
439 inline void asio_handler_invoke(Function& function,
440 range_connect_op<Protocol, Executor, 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 Executor, typename Protocol,
448 typename EndpointSequence, typename ConnectCondition,
449 typename RangeConnectHandler>
450 inline void asio_handler_invoke(const Function& function,
451 range_connect_op<Protocol, Executor, 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, typename Executor>
459 class initiate_async_range_connect
460 {
461 public:
462 typedef Executor executor_type;
463
464 explicit initiate_async_range_connect(basic_socket<Protocol, Executor>& s)
465 : socket_(s)
466 {
467 }
468
469 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
470 {
471 return socket_.get_executor();
472 }
473
474 template <typename RangeConnectHandler,
475 typename EndpointSequence, typename ConnectCondition>
476 void operator()(BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
477 const EndpointSequence& endpoints,
478 const ConnectCondition& connect_condition) const
479 {
480 // If you get an error on the following line it means that your
481 // handler does not meet the documented type requirements for an
482 // RangeConnectHandler.
483 BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK(RangeConnectHandler,
484 handler, typename Protocol::endpoint) type_check;
485
486 non_const_lvalue<RangeConnectHandler> handler2(handler);
487 range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,
488 typename decay<RangeConnectHandler>::type>(socket_, endpoints,
489 connect_condition, handler2.value)(boost::system::error_code(), 1);
490 }
491
492 private:
493 basic_socket<Protocol, Executor>& socket_;
494 };
495
496 template <typename Protocol, typename Executor, typename Iterator,
497 typename ConnectCondition, typename IteratorConnectHandler>
498 class iterator_connect_op : base_from_connect_condition<ConnectCondition>
499 {
500 public:
501 iterator_connect_op(basic_socket<Protocol, Executor>& sock,
502 const Iterator& begin, const Iterator& end,
503 const ConnectCondition& connect_condition,
504 IteratorConnectHandler& handler)
505 : base_from_connect_condition<ConnectCondition>(connect_condition),
506 socket_(sock),
507 iter_(begin),
508 end_(end),
509 start_(0),
510 handler_(BOOST_ASIO_MOVE_CAST(IteratorConnectHandler)(handler))
511 {
512 }
513
514 #if defined(BOOST_ASIO_HAS_MOVE)
515 iterator_connect_op(const iterator_connect_op& other)
516 : base_from_connect_condition<ConnectCondition>(other),
517 socket_(other.socket_),
518 iter_(other.iter_),
519 end_(other.end_),
520 start_(other.start_),
521 handler_(other.handler_)
522 {
523 }
524
525 iterator_connect_op(iterator_connect_op&& other)
526 : base_from_connect_condition<ConnectCondition>(other),
527 socket_(other.socket_),
528 iter_(other.iter_),
529 end_(other.end_),
530 start_(other.start_),
531 handler_(BOOST_ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_))
532 {
533 }
534 #endif // defined(BOOST_ASIO_HAS_MOVE)
535
536 void operator()(boost::system::error_code ec, int start = 0)
537 {
538 switch (start_ = start)
539 {
540 case 1:
541 for (;;)
542 {
543 this->check_condition(ec, iter_, end_);
544
545 if (iter_ != end_)
546 {
547 socket_.close(ec);
548 socket_.async_connect(*iter_,
549 BOOST_ASIO_MOVE_CAST(iterator_connect_op)(*this));
550 return;
551 }
552
553 if (start)
554 {
555 ec = boost::asio::error::not_found;
556 boost::asio::post(socket_.get_executor(),
557 detail::bind_handler(
558 BOOST_ASIO_MOVE_CAST(iterator_connect_op)(*this), ec));
559 return;
560 }
561
562 /* fall-through */ default:
563
564 if (iter_ == end_)
565 break;
566
567 if (!socket_.is_open())
568 {
569 ec = boost::asio::error::operation_aborted;
570 break;
571 }
572
573 if (!ec)
574 break;
575
576 ++iter_;
577 }
578
579 handler_(static_cast<const boost::system::error_code&>(ec),
580 static_cast<const Iterator&>(iter_));
581 }
582 }
583
584 //private:
585 basic_socket<Protocol, Executor>& socket_;
586 Iterator iter_;
587 Iterator end_;
588 int start_;
589 IteratorConnectHandler handler_;
590 };
591
592 template <typename Protocol, typename Executor, typename Iterator,
593 typename ConnectCondition, typename IteratorConnectHandler>
594 inline void* asio_handler_allocate(std::size_t size,
595 iterator_connect_op<Protocol, Executor, Iterator,
596 ConnectCondition, IteratorConnectHandler>* this_handler)
597 {
598 return boost_asio_handler_alloc_helpers::allocate(
599 size, this_handler->handler_);
600 }
601
602 template <typename Protocol, typename Executor, typename Iterator,
603 typename ConnectCondition, typename IteratorConnectHandler>
604 inline void asio_handler_deallocate(void* pointer, std::size_t size,
605 iterator_connect_op<Protocol, Executor, Iterator,
606 ConnectCondition, IteratorConnectHandler>* this_handler)
607 {
608 boost_asio_handler_alloc_helpers::deallocate(
609 pointer, size, this_handler->handler_);
610 }
611
612 template <typename Protocol, typename Executor, typename Iterator,
613 typename ConnectCondition, typename IteratorConnectHandler>
614 inline bool asio_handler_is_continuation(
615 iterator_connect_op<Protocol, Executor, Iterator,
616 ConnectCondition, IteratorConnectHandler>* this_handler)
617 {
618 return boost_asio_handler_cont_helpers::is_continuation(
619 this_handler->handler_);
620 }
621
622 template <typename Function, typename Executor, typename Protocol,
623 typename Iterator, typename ConnectCondition,
624 typename IteratorConnectHandler>
625 inline void asio_handler_invoke(Function& function,
626 iterator_connect_op<Protocol, Executor, Iterator,
627 ConnectCondition, IteratorConnectHandler>* this_handler)
628 {
629 boost_asio_handler_invoke_helpers::invoke(
630 function, this_handler->handler_);
631 }
632
633 template <typename Function, typename Executor, typename Protocol,
634 typename Iterator, typename ConnectCondition,
635 typename IteratorConnectHandler>
636 inline void asio_handler_invoke(const Function& function,
637 iterator_connect_op<Protocol, Executor, Iterator,
638 ConnectCondition, IteratorConnectHandler>* this_handler)
639 {
640 boost_asio_handler_invoke_helpers::invoke(
641 function, this_handler->handler_);
642 }
643
644 template <typename Protocol, typename Executor>
645 class initiate_async_iterator_connect
646 {
647 public:
648 typedef Executor executor_type;
649
650 explicit initiate_async_iterator_connect(
651 basic_socket<Protocol, Executor>& s)
652 : socket_(s)
653 {
654 }
655
656 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
657 {
658 return socket_.get_executor();
659 }
660
661 template <typename IteratorConnectHandler,
662 typename Iterator, typename ConnectCondition>
663 void operator()(BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
664 Iterator begin, Iterator end,
665 const ConnectCondition& connect_condition) const
666 {
667 // If you get an error on the following line it means that your
668 // handler does not meet the documented type requirements for an
669 // IteratorConnectHandler.
670 BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
671 IteratorConnectHandler, handler, Iterator) type_check;
672
673 non_const_lvalue<IteratorConnectHandler> handler2(handler);
674 iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,
675 typename decay<IteratorConnectHandler>::type>(socket_, begin, end,
676 connect_condition, handler2.value)(boost::system::error_code(), 1);
677 }
678
679 private:
680 basic_socket<Protocol, Executor>& socket_;
681 };
682 } // namespace detail
683
684 #if !defined(GENERATING_DOCUMENTATION)
685
686 template <typename Protocol, typename Executor, typename EndpointSequence,
687 typename ConnectCondition, typename RangeConnectHandler, typename Allocator>
688 struct associated_allocator<
689 detail::range_connect_op<Protocol, Executor, EndpointSequence,
690 ConnectCondition, RangeConnectHandler>, Allocator>
691 {
692 typedef typename associated_allocator<
693 RangeConnectHandler, Allocator>::type type;
694
695 static type get(
696 const detail::range_connect_op<Protocol, Executor, EndpointSequence,
697 ConnectCondition, RangeConnectHandler>& h,
698 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
699 {
700 return associated_allocator<RangeConnectHandler,
701 Allocator>::get(h.handler_, a);
702 }
703 };
704
705 template <typename Protocol, typename Executor, typename EndpointSequence,
706 typename ConnectCondition, typename RangeConnectHandler, typename Executor1>
707 struct associated_executor<
708 detail::range_connect_op<Protocol, Executor, EndpointSequence,
709 ConnectCondition, RangeConnectHandler>, Executor1>
710 {
711 typedef typename associated_executor<
712 RangeConnectHandler, Executor1>::type type;
713
714 static type get(
715 const detail::range_connect_op<Protocol, Executor, EndpointSequence,
716 ConnectCondition, RangeConnectHandler>& h,
717 const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
718 {
719 return associated_executor<RangeConnectHandler,
720 Executor1>::get(h.handler_, ex);
721 }
722 };
723
724 template <typename Protocol, typename Executor, typename Iterator,
725 typename ConnectCondition, typename IteratorConnectHandler,
726 typename Allocator>
727 struct associated_allocator<
728 detail::iterator_connect_op<Protocol, Executor,
729 Iterator, ConnectCondition, IteratorConnectHandler>,
730 Allocator>
731 {
732 typedef typename associated_allocator<
733 IteratorConnectHandler, Allocator>::type type;
734
735 static type get(
736 const detail::iterator_connect_op<Protocol, Executor,
737 Iterator, ConnectCondition, IteratorConnectHandler>& h,
738 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
739 {
740 return associated_allocator<IteratorConnectHandler,
741 Allocator>::get(h.handler_, a);
742 }
743 };
744
745 template <typename Protocol, typename Executor, typename Iterator,
746 typename ConnectCondition, typename IteratorConnectHandler,
747 typename Executor1>
748 struct associated_executor<
749 detail::iterator_connect_op<Protocol, Executor,
750 Iterator, ConnectCondition, IteratorConnectHandler>,
751 Executor1>
752 {
753 typedef typename associated_executor<
754 IteratorConnectHandler, Executor1>::type type;
755
756 static type get(
757 const detail::iterator_connect_op<Protocol, Executor,
758 Iterator, ConnectCondition, IteratorConnectHandler>& h,
759 const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
760 {
761 return associated_executor<IteratorConnectHandler,
762 Executor1>::get(h.handler_, ex);
763 }
764 };
765
766 #endif // !defined(GENERATING_DOCUMENTATION)
767
768 template <typename Protocol, typename Executor, typename EndpointSequence,
769 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
770 typename Protocol::endpoint)) RangeConnectHandler>
771 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler,
772 void (boost::system::error_code, typename Protocol::endpoint))
773 async_connect(basic_socket<Protocol, Executor>& s,
774 const EndpointSequence& endpoints,
775 BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
776 typename enable_if<is_endpoint_sequence<
777 EndpointSequence>::value>::type*)
778 {
779 return async_initiate<RangeConnectHandler,
780 void (boost::system::error_code, typename Protocol::endpoint)>(
781 detail::initiate_async_range_connect<Protocol, Executor>(s),
782 handler, endpoints, detail::default_connect_condition());
783 }
784
785 #if !defined(BOOST_ASIO_NO_DEPRECATED)
786 template <typename Protocol, typename Executor, typename Iterator,
787 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
788 Iterator)) IteratorConnectHandler>
789 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
790 void (boost::system::error_code, Iterator))
791 async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
792 BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
793 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
794 {
795 return async_initiate<IteratorConnectHandler,
796 void (boost::system::error_code, Iterator)>(
797 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
798 handler, begin, Iterator(), detail::default_connect_condition());
799 }
800 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
801
802 template <typename Protocol, typename Executor, typename Iterator,
803 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
804 Iterator)) IteratorConnectHandler>
805 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
806 void (boost::system::error_code, Iterator))
807 async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
808 BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
809 {
810 return async_initiate<IteratorConnectHandler,
811 void (boost::system::error_code, Iterator)>(
812 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
813 handler, begin, end, detail::default_connect_condition());
814 }
815
816 template <typename Protocol, typename Executor,
817 typename EndpointSequence, typename ConnectCondition,
818 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
819 typename Protocol::endpoint)) RangeConnectHandler>
820 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler,
821 void (boost::system::error_code, typename Protocol::endpoint))
822 async_connect(basic_socket<Protocol, Executor>& s,
823 const EndpointSequence& endpoints, ConnectCondition connect_condition,
824 BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
825 typename enable_if<is_endpoint_sequence<
826 EndpointSequence>::value>::type*)
827 {
828 return async_initiate<RangeConnectHandler,
829 void (boost::system::error_code, typename Protocol::endpoint)>(
830 detail::initiate_async_range_connect<Protocol, Executor>(s),
831 handler, endpoints, connect_condition);
832 }
833
834 #if !defined(BOOST_ASIO_NO_DEPRECATED)
835 template <typename Protocol, typename Executor,
836 typename Iterator, typename ConnectCondition,
837 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
838 Iterator)) IteratorConnectHandler>
839 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
840 void (boost::system::error_code, Iterator))
841 async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
842 ConnectCondition connect_condition,
843 BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
844 typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
845 {
846 return async_initiate<IteratorConnectHandler,
847 void (boost::system::error_code, Iterator)>(
848 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
849 handler, begin, Iterator(), connect_condition);
850 }
851 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
852
853 template <typename Protocol, typename Executor,
854 typename Iterator, typename ConnectCondition,
855 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
856 Iterator)) IteratorConnectHandler>
857 inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(IteratorConnectHandler,
858 void (boost::system::error_code, Iterator))
859 async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
860 Iterator end, ConnectCondition connect_condition,
861 BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
862 {
863 return async_initiate<IteratorConnectHandler,
864 void (boost::system::error_code, Iterator)>(
865 detail::initiate_async_iterator_connect<Protocol, Executor>(s),
866 handler, begin, end, connect_condition);
867 }
868
869 } // namespace asio
870 } // namespace boost
871
872 #include <boost/asio/detail/pop_options.hpp>
873
874 #endif // BOOST_ASIO_IMPL_CONNECT_HPP