Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:08:22

0001 //
0002 // connect.hpp
0003 // ~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_CONNECT_HPP
0012 #define BOOST_ASIO_CONNECT_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/async_result.hpp>
0020 #include <boost/asio/basic_socket.hpp>
0021 #include <boost/asio/detail/type_traits.hpp>
0022 #include <boost/asio/error.hpp>
0023 
0024 #include <boost/asio/detail/push_options.hpp>
0025 
0026 namespace boost {
0027 namespace asio {
0028 
0029 namespace detail
0030 {
0031   struct default_connect_condition;
0032   template <typename, typename> class initiate_async_range_connect;
0033   template <typename, typename> class initiate_async_iterator_connect;
0034 
0035   template <typename T, typename = void, typename = void>
0036   struct is_endpoint_sequence_helper : false_type
0037   {
0038   };
0039 
0040   template <typename T>
0041   struct is_endpoint_sequence_helper<T,
0042       void_t<
0043         decltype(declval<T>().begin())
0044       >,
0045       void_t<
0046         decltype(declval<T>().end())
0047       >
0048     > : true_type
0049   {
0050   };
0051 
0052   template <typename T, typename Iterator, typename = void>
0053   struct is_connect_condition_helper : false_type
0054   {
0055   };
0056 
0057   template <typename T, typename Iterator>
0058   struct is_connect_condition_helper<T, Iterator,
0059       enable_if_t<
0060         is_same<
0061           result_of_t<T(boost::system::error_code, Iterator)>,
0062           Iterator
0063         >::value
0064       >
0065     > : true_type
0066   {
0067   };
0068 
0069   template <typename T, typename Iterator>
0070   struct is_connect_condition_helper<T, Iterator,
0071       enable_if_t<
0072         is_same<
0073           result_of_t<T(boost::system::error_code,
0074             decltype(*declval<Iterator>()))>,
0075           bool
0076         >::value
0077       >
0078     > : true_type
0079   {
0080   };
0081 
0082   struct default_connect_condition
0083   {
0084     template <typename Endpoint>
0085     bool operator()(const boost::system::error_code&, const Endpoint&)
0086     {
0087       return true;
0088     }
0089   };
0090 } // namespace detail
0091 
0092 #if defined(GENERATING_DOCUMENTATION)
0093 
0094 /// Type trait used to determine whether a type is an endpoint sequence that can
0095 /// be used with with @c connect and @c async_connect.
0096 template <typename T>
0097 struct is_endpoint_sequence
0098 {
0099   /// The value member is true if the type may be used as an endpoint sequence.
0100   static const bool value = automatically_determined;
0101 };
0102 
0103 /// Trait for determining whether a function object is a connect condition that
0104 /// can be used with @c connect and @c async_connect.
0105 template <typename T, typename Iterator>
0106 struct is_connect_condition
0107 {
0108   /// The value member is true if the type may be used as a connect condition.
0109   static constexpr bool value = automatically_determined;
0110 };
0111 
0112 #else // defined(GENERATING_DOCUMENTATION)
0113 
0114 template <typename T>
0115 struct is_endpoint_sequence : detail::is_endpoint_sequence_helper<T>
0116 {
0117 };
0118 
0119 template <typename T, typename Iterator>
0120 struct is_connect_condition : detail::is_connect_condition_helper<T, Iterator>
0121 {
0122 };
0123 
0124 #endif // defined(GENERATING_DOCUMENTATION)
0125 
0126 /**
0127  * @defgroup connect boost::asio::connect
0128  *
0129  * @brief The @c connect function is a composed operation that establishes a
0130  * socket connection by trying each endpoint in a sequence.
0131  */
0132 /*@{*/
0133 
0134 /// Establishes a socket connection by trying each endpoint in a sequence.
0135 /**
0136  * This function attempts to connect a socket to one of a sequence of
0137  * endpoints. It does this by repeated calls to the socket's @c connect member
0138  * function, once for each endpoint in the sequence, until a connection is
0139  * successfully established.
0140  *
0141  * @param s The socket to be connected. If the socket is already open, it will
0142  * be closed.
0143  *
0144  * @param endpoints A sequence of endpoints.
0145  *
0146  * @returns The successfully connected endpoint.
0147  *
0148  * @throws boost::system::system_error Thrown on failure. If the sequence is
0149  * empty, the associated @c error_code is boost::asio::error::not_found.
0150  * Otherwise, contains the error from the last connection attempt.
0151  *
0152  * @par Example
0153  * @code tcp::resolver r(my_context);
0154  * tcp::resolver::query q("host", "service");
0155  * tcp::socket s(my_context);
0156  * boost::asio::connect(s, r.resolve(q)); @endcode
0157  */
0158 template <typename Protocol, typename Executor, typename EndpointSequence>
0159 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0160     const EndpointSequence& endpoints,
0161     constraint_t<
0162       is_endpoint_sequence<EndpointSequence>::value
0163     > = 0);
0164 
0165 /// Establishes a socket connection by trying each endpoint in a sequence.
0166 /**
0167  * This function attempts to connect a socket to one of a sequence of
0168  * endpoints. It does this by repeated calls to the socket's @c connect member
0169  * function, once for each endpoint in the sequence, until a connection is
0170  * successfully established.
0171  *
0172  * @param s The socket to be connected. If the socket is already open, it will
0173  * be closed.
0174  *
0175  * @param endpoints A sequence of endpoints.
0176  *
0177  * @param ec Set to indicate what error occurred, if any. If the sequence is
0178  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0179  * from the last connection attempt.
0180  *
0181  * @returns On success, the successfully connected endpoint. Otherwise, a
0182  * default-constructed endpoint.
0183  *
0184  * @par Example
0185  * @code tcp::resolver r(my_context);
0186  * tcp::resolver::query q("host", "service");
0187  * tcp::socket s(my_context);
0188  * boost::system::error_code ec;
0189  * boost::asio::connect(s, r.resolve(q), ec);
0190  * if (ec)
0191  * {
0192  *   // An error occurred.
0193  * } @endcode
0194  */
0195 template <typename Protocol, typename Executor, typename EndpointSequence>
0196 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0197     const EndpointSequence& endpoints, boost::system::error_code& ec,
0198     constraint_t<
0199       is_endpoint_sequence<EndpointSequence>::value
0200     > = 0);
0201 
0202 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0203 /// (Deprecated: Use range overload.) Establishes a socket connection by trying
0204 /// each endpoint in a sequence.
0205 /**
0206  * This function attempts to connect a socket to one of a sequence of
0207  * endpoints. It does this by repeated calls to the socket's @c connect member
0208  * function, once for each endpoint in the sequence, until a connection is
0209  * successfully established.
0210  *
0211  * @param s The socket to be connected. If the socket is already open, it will
0212  * be closed.
0213  *
0214  * @param begin An iterator pointing to the start of a sequence of endpoints.
0215  *
0216  * @returns On success, an iterator denoting the successfully connected
0217  * endpoint. Otherwise, the end iterator.
0218  *
0219  * @throws boost::system::system_error Thrown on failure. If the sequence is
0220  * empty, the associated @c error_code is boost::asio::error::not_found.
0221  * Otherwise, contains the error from the last connection attempt.
0222  *
0223  * @note This overload assumes that a default constructed object of type @c
0224  * Iterator represents the end of the sequence. This is a valid assumption for
0225  * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
0226  */
0227 template <typename Protocol, typename Executor, typename Iterator>
0228 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0229     constraint_t<
0230       !is_endpoint_sequence<Iterator>::value
0231     > = 0);
0232 
0233 /// (Deprecated: Use range overload.) Establishes a socket connection by trying
0234 /// each endpoint in a sequence.
0235 /**
0236  * This function attempts to connect a socket to one of a sequence of
0237  * endpoints. It does this by repeated calls to the socket's @c connect member
0238  * function, once for each endpoint in the sequence, until a connection is
0239  * successfully established.
0240  *
0241  * @param s The socket to be connected. If the socket is already open, it will
0242  * be closed.
0243  *
0244  * @param begin An iterator pointing to the start of a sequence of endpoints.
0245  *
0246  * @param ec Set to indicate what error occurred, if any. If the sequence is
0247  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0248  * from the last connection attempt.
0249  *
0250  * @returns On success, an iterator denoting the successfully connected
0251  * endpoint. Otherwise, the end iterator.
0252  *
0253  * @note This overload assumes that a default constructed object of type @c
0254  * Iterator represents the end of the sequence. This is a valid assumption for
0255  * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
0256  */
0257 template <typename Protocol, typename Executor, typename Iterator>
0258 Iterator connect(basic_socket<Protocol, Executor>& s,
0259     Iterator begin, boost::system::error_code& ec,
0260     constraint_t<
0261       !is_endpoint_sequence<Iterator>::value
0262     > = 0);
0263 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
0264 
0265 /// Establishes a socket connection by trying each endpoint in a sequence.
0266 /**
0267  * This function attempts to connect a socket to one of a sequence of
0268  * endpoints. It does this by repeated calls to the socket's @c connect member
0269  * function, once for each endpoint in the sequence, until a connection is
0270  * successfully established.
0271  *
0272  * @param s The socket to be connected. If the socket is already open, it will
0273  * be closed.
0274  *
0275  * @param begin An iterator pointing to the start of a sequence of endpoints.
0276  *
0277  * @param end An iterator pointing to the end of a sequence of endpoints.
0278  *
0279  * @returns An iterator denoting the successfully connected endpoint.
0280  *
0281  * @throws boost::system::system_error Thrown on failure. If the sequence is
0282  * empty, the associated @c error_code is boost::asio::error::not_found.
0283  * Otherwise, contains the error from the last connection attempt.
0284  *
0285  * @par Example
0286  * @code tcp::resolver r(my_context);
0287  * tcp::resolver::query q("host", "service");
0288  * tcp::resolver::results_type e = r.resolve(q);
0289  * tcp::socket s(my_context);
0290  * boost::asio::connect(s, e.begin(), e.end()); @endcode
0291  */
0292 template <typename Protocol, typename Executor, typename Iterator>
0293 Iterator connect(basic_socket<Protocol, Executor>& s,
0294     Iterator begin, Iterator end);
0295 
0296 /// Establishes a socket connection by trying each endpoint in a sequence.
0297 /**
0298  * This function attempts to connect a socket to one of a sequence of
0299  * endpoints. It does this by repeated calls to the socket's @c connect member
0300  * function, once for each endpoint in the sequence, until a connection is
0301  * successfully established.
0302  *
0303  * @param s The socket to be connected. If the socket is already open, it will
0304  * be closed.
0305  *
0306  * @param begin An iterator pointing to the start of a sequence of endpoints.
0307  *
0308  * @param end An iterator pointing to the end of a sequence of endpoints.
0309  *
0310  * @param ec Set to indicate what error occurred, if any. If the sequence is
0311  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0312  * from the last connection attempt.
0313  *
0314  * @returns On success, an iterator denoting the successfully connected
0315  * endpoint. Otherwise, the end iterator.
0316  *
0317  * @par Example
0318  * @code tcp::resolver r(my_context);
0319  * tcp::resolver::query q("host", "service");
0320  * tcp::resolver::results_type e = r.resolve(q);
0321  * tcp::socket s(my_context);
0322  * boost::system::error_code ec;
0323  * boost::asio::connect(s, e.begin(), e.end(), ec);
0324  * if (ec)
0325  * {
0326  *   // An error occurred.
0327  * } @endcode
0328  */
0329 template <typename Protocol, typename Executor, typename Iterator>
0330 Iterator connect(basic_socket<Protocol, Executor>& s,
0331     Iterator begin, Iterator end, boost::system::error_code& ec);
0332 
0333 /// Establishes a socket connection by trying each endpoint in a sequence.
0334 /**
0335  * This function attempts to connect a socket to one of a sequence of
0336  * endpoints. It does this by repeated calls to the socket's @c connect member
0337  * function, once for each endpoint in the sequence, until a connection is
0338  * successfully established.
0339  *
0340  * @param s The socket to be connected. If the socket is already open, it will
0341  * be closed.
0342  *
0343  * @param endpoints A sequence of endpoints.
0344  *
0345  * @param connect_condition A function object that is called prior to each
0346  * connection attempt. The signature of the function object must be:
0347  * @code bool connect_condition(
0348  *     const boost::system::error_code& ec,
0349  *     const typename Protocol::endpoint& next); @endcode
0350  * The @c ec parameter contains the result from the most recent connect
0351  * operation. Before the first connection attempt, @c ec is always set to
0352  * indicate success. The @c next parameter is the next endpoint to be tried.
0353  * The function object should return true if the next endpoint should be tried,
0354  * and false if it should be skipped.
0355  *
0356  * @returns The successfully connected endpoint.
0357  *
0358  * @throws boost::system::system_error Thrown on failure. If the sequence is
0359  * empty, the associated @c error_code is boost::asio::error::not_found.
0360  * Otherwise, contains the error from the last connection attempt.
0361  *
0362  * @par Example
0363  * The following connect condition function object can be used to output
0364  * information about the individual connection attempts:
0365  * @code struct my_connect_condition
0366  * {
0367  *   bool operator()(
0368  *       const boost::system::error_code& ec,
0369  *       const::tcp::endpoint& next)
0370  *   {
0371  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0372  *     std::cout << "Trying: " << next << std::endl;
0373  *     return true;
0374  *   }
0375  * }; @endcode
0376  * It would be used with the boost::asio::connect function as follows:
0377  * @code tcp::resolver r(my_context);
0378  * tcp::resolver::query q("host", "service");
0379  * tcp::socket s(my_context);
0380  * tcp::endpoint e = boost::asio::connect(s,
0381  *     r.resolve(q), my_connect_condition());
0382  * std::cout << "Connected to: " << e << std::endl; @endcode
0383  */
0384 template <typename Protocol, typename Executor,
0385     typename EndpointSequence, typename ConnectCondition>
0386 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0387     const EndpointSequence& endpoints, ConnectCondition connect_condition,
0388     constraint_t<
0389       is_endpoint_sequence<EndpointSequence>::value
0390     > = 0,
0391     constraint_t<
0392       is_connect_condition<ConnectCondition,
0393         decltype(declval<const EndpointSequence&>().begin())>::value
0394     > = 0);
0395 
0396 /// Establishes a socket connection by trying each endpoint in a sequence.
0397 /**
0398  * This function attempts to connect a socket to one of a sequence of
0399  * endpoints. It does this by repeated calls to the socket's @c connect member
0400  * function, once for each endpoint in the sequence, until a connection is
0401  * successfully established.
0402  *
0403  * @param s The socket to be connected. If the socket is already open, it will
0404  * be closed.
0405  *
0406  * @param endpoints A sequence of endpoints.
0407  *
0408  * @param connect_condition A function object that is called prior to each
0409  * connection attempt. The signature of the function object must be:
0410  * @code bool connect_condition(
0411  *     const boost::system::error_code& ec,
0412  *     const typename Protocol::endpoint& next); @endcode
0413  * The @c ec parameter contains the result from the most recent connect
0414  * operation. Before the first connection attempt, @c ec is always set to
0415  * indicate success. The @c next parameter is the next endpoint to be tried.
0416  * The function object should return true if the next endpoint should be tried,
0417  * and false if it should be skipped.
0418  *
0419  * @param ec Set to indicate what error occurred, if any. If the sequence is
0420  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0421  * from the last connection attempt.
0422  *
0423  * @returns On success, the successfully connected endpoint. Otherwise, a
0424  * default-constructed endpoint.
0425  *
0426  * @par Example
0427  * The following connect condition function object can be used to output
0428  * information about the individual connection attempts:
0429  * @code struct my_connect_condition
0430  * {
0431  *   bool operator()(
0432  *       const boost::system::error_code& ec,
0433  *       const::tcp::endpoint& next)
0434  *   {
0435  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0436  *     std::cout << "Trying: " << next << std::endl;
0437  *     return true;
0438  *   }
0439  * }; @endcode
0440  * It would be used with the boost::asio::connect function as follows:
0441  * @code tcp::resolver r(my_context);
0442  * tcp::resolver::query q("host", "service");
0443  * tcp::socket s(my_context);
0444  * boost::system::error_code ec;
0445  * tcp::endpoint e = boost::asio::connect(s,
0446  *     r.resolve(q), my_connect_condition(), ec);
0447  * if (ec)
0448  * {
0449  *   // An error occurred.
0450  * }
0451  * else
0452  * {
0453  *   std::cout << "Connected to: " << e << std::endl;
0454  * } @endcode
0455  */
0456 template <typename Protocol, typename Executor,
0457     typename EndpointSequence, typename ConnectCondition>
0458 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0459     const EndpointSequence& endpoints, ConnectCondition connect_condition,
0460     boost::system::error_code& ec,
0461     constraint_t<
0462       is_endpoint_sequence<EndpointSequence>::value
0463     > = 0,
0464     constraint_t<
0465       is_connect_condition<ConnectCondition,
0466         decltype(declval<const EndpointSequence&>().begin())>::value
0467     > = 0);
0468 
0469 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0470 /// (Deprecated: Use range overload.) Establishes a socket connection by trying
0471 /// each endpoint in a sequence.
0472 /**
0473  * This function attempts to connect a socket to one of a sequence of
0474  * endpoints. It does this by repeated calls to the socket's @c connect member
0475  * function, once for each endpoint in the sequence, until a connection is
0476  * successfully established.
0477  *
0478  * @param s The socket to be connected. If the socket is already open, it will
0479  * be closed.
0480  *
0481  * @param begin An iterator pointing to the start of a sequence of endpoints.
0482  *
0483  * @param connect_condition A function object that is called prior to each
0484  * connection attempt. The signature of the function object must be:
0485  * @code bool connect_condition(
0486  *     const boost::system::error_code& ec,
0487  *     const typename Protocol::endpoint& next); @endcode
0488  * The @c ec parameter contains the result from the most recent connect
0489  * operation. Before the first connection attempt, @c ec is always set to
0490  * indicate success. The @c next parameter is the next endpoint to be tried.
0491  * The function object should return true if the next endpoint should be tried,
0492  * and false if it should be skipped.
0493  *
0494  * @returns On success, an iterator denoting the successfully connected
0495  * endpoint. Otherwise, the end iterator.
0496  *
0497  * @throws boost::system::system_error Thrown on failure. If the sequence is
0498  * empty, the associated @c error_code is boost::asio::error::not_found.
0499  * Otherwise, contains the error from the last connection attempt.
0500  *
0501  * @note This overload assumes that a default constructed object of type @c
0502  * Iterator represents the end of the sequence. This is a valid assumption for
0503  * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
0504  */
0505 template <typename Protocol, typename Executor,
0506     typename Iterator, typename ConnectCondition>
0507 Iterator connect(basic_socket<Protocol, Executor>& s,
0508     Iterator begin, ConnectCondition connect_condition,
0509     constraint_t<
0510       !is_endpoint_sequence<Iterator>::value
0511     > = 0,
0512     constraint_t<
0513       is_connect_condition<ConnectCondition, Iterator>::value
0514     > = 0);
0515 
0516 /// (Deprecated: Use range overload.) Establishes a socket connection by trying
0517 /// each endpoint in a sequence.
0518 /**
0519  * This function attempts to connect a socket to one of a sequence of
0520  * endpoints. It does this by repeated calls to the socket's @c connect member
0521  * function, once for each endpoint in the sequence, until a connection is
0522  * successfully established.
0523  *
0524  * @param s The socket to be connected. If the socket is already open, it will
0525  * be closed.
0526  *
0527  * @param begin An iterator pointing to the start of a sequence of endpoints.
0528  *
0529  * @param connect_condition A function object that is called prior to each
0530  * connection attempt. The signature of the function object must be:
0531  * @code bool connect_condition(
0532  *     const boost::system::error_code& ec,
0533  *     const typename Protocol::endpoint& next); @endcode
0534  * The @c ec parameter contains the result from the most recent connect
0535  * operation. Before the first connection attempt, @c ec is always set to
0536  * indicate success. The @c next parameter is the next endpoint to be tried.
0537  * The function object should return true if the next endpoint should be tried,
0538  * and false if it should be skipped.
0539  *
0540  * @param ec Set to indicate what error occurred, if any. If the sequence is
0541  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0542  * from the last connection attempt.
0543  *
0544  * @returns On success, an iterator denoting the successfully connected
0545  * endpoint. Otherwise, the end iterator.
0546  *
0547  * @note This overload assumes that a default constructed object of type @c
0548  * Iterator represents the end of the sequence. This is a valid assumption for
0549  * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
0550  */
0551 template <typename Protocol, typename Executor,
0552     typename Iterator, typename ConnectCondition>
0553 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0554     ConnectCondition connect_condition, boost::system::error_code& ec,
0555     constraint_t<
0556       !is_endpoint_sequence<Iterator>::value
0557     > = 0,
0558     constraint_t<
0559       is_connect_condition<ConnectCondition, Iterator>::value
0560     > = 0);
0561 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
0562 
0563 /// Establishes a socket connection by trying each endpoint in a sequence.
0564 /**
0565  * This function attempts to connect a socket to one of a sequence of
0566  * endpoints. It does this by repeated calls to the socket's @c connect member
0567  * function, once for each endpoint in the sequence, until a connection is
0568  * successfully established.
0569  *
0570  * @param s The socket to be connected. If the socket is already open, it will
0571  * be closed.
0572  *
0573  * @param begin An iterator pointing to the start of a sequence of endpoints.
0574  *
0575  * @param end An iterator pointing to the end of a sequence of endpoints.
0576  *
0577  * @param connect_condition A function object that is called prior to each
0578  * connection attempt. The signature of the function object must be:
0579  * @code bool connect_condition(
0580  *     const boost::system::error_code& ec,
0581  *     const typename Protocol::endpoint& next); @endcode
0582  * The @c ec parameter contains the result from the most recent connect
0583  * operation. Before the first connection attempt, @c ec is always set to
0584  * indicate success. The @c next parameter is the next endpoint to be tried.
0585  * The function object should return true if the next endpoint should be tried,
0586  * and false if it should be skipped.
0587  *
0588  * @returns An iterator denoting the successfully connected endpoint.
0589  *
0590  * @throws boost::system::system_error Thrown on failure. If the sequence is
0591  * empty, the associated @c error_code is boost::asio::error::not_found.
0592  * Otherwise, contains the error from the last connection attempt.
0593  *
0594  * @par Example
0595  * The following connect condition function object can be used to output
0596  * information about the individual connection attempts:
0597  * @code struct my_connect_condition
0598  * {
0599  *   bool operator()(
0600  *       const boost::system::error_code& ec,
0601  *       const::tcp::endpoint& next)
0602  *   {
0603  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0604  *     std::cout << "Trying: " << next << std::endl;
0605  *     return true;
0606  *   }
0607  * }; @endcode
0608  * It would be used with the boost::asio::connect function as follows:
0609  * @code tcp::resolver r(my_context);
0610  * tcp::resolver::query q("host", "service");
0611  * tcp::resolver::results_type e = r.resolve(q);
0612  * tcp::socket s(my_context);
0613  * tcp::resolver::results_type::iterator i = boost::asio::connect(
0614  *     s, e.begin(), e.end(), my_connect_condition());
0615  * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
0616  */
0617 template <typename Protocol, typename Executor,
0618     typename Iterator, typename ConnectCondition>
0619 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0620     Iterator end, ConnectCondition connect_condition,
0621     constraint_t<
0622       is_connect_condition<ConnectCondition, Iterator>::value
0623     > = 0);
0624 
0625 /// Establishes a socket connection by trying each endpoint in a sequence.
0626 /**
0627  * This function attempts to connect a socket to one of a sequence of
0628  * endpoints. It does this by repeated calls to the socket's @c connect member
0629  * function, once for each endpoint in the sequence, until a connection is
0630  * successfully established.
0631  *
0632  * @param s The socket to be connected. If the socket is already open, it will
0633  * be closed.
0634  *
0635  * @param begin An iterator pointing to the start of a sequence of endpoints.
0636  *
0637  * @param end An iterator pointing to the end of a sequence of endpoints.
0638  *
0639  * @param connect_condition A function object that is called prior to each
0640  * connection attempt. The signature of the function object must be:
0641  * @code bool connect_condition(
0642  *     const boost::system::error_code& ec,
0643  *     const typename Protocol::endpoint& next); @endcode
0644  * The @c ec parameter contains the result from the most recent connect
0645  * operation. Before the first connection attempt, @c ec is always set to
0646  * indicate success. The @c next parameter is the next endpoint to be tried.
0647  * The function object should return true if the next endpoint should be tried,
0648  * and false if it should be skipped.
0649  *
0650  * @param ec Set to indicate what error occurred, if any. If the sequence is
0651  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0652  * from the last connection attempt.
0653  *
0654  * @returns On success, an iterator denoting the successfully connected
0655  * endpoint. Otherwise, the end iterator.
0656  *
0657  * @par Example
0658  * The following connect condition function object can be used to output
0659  * information about the individual connection attempts:
0660  * @code struct my_connect_condition
0661  * {
0662  *   bool operator()(
0663  *       const boost::system::error_code& ec,
0664  *       const::tcp::endpoint& next)
0665  *   {
0666  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0667  *     std::cout << "Trying: " << next << std::endl;
0668  *     return true;
0669  *   }
0670  * }; @endcode
0671  * It would be used with the boost::asio::connect function as follows:
0672  * @code tcp::resolver r(my_context);
0673  * tcp::resolver::query q("host", "service");
0674  * tcp::resolver::results_type e = r.resolve(q);
0675  * tcp::socket s(my_context);
0676  * boost::system::error_code ec;
0677  * tcp::resolver::results_type::iterator i = boost::asio::connect(
0678  *     s, e.begin(), e.end(), my_connect_condition());
0679  * if (ec)
0680  * {
0681  *   // An error occurred.
0682  * }
0683  * else
0684  * {
0685  *   std::cout << "Connected to: " << i->endpoint() << std::endl;
0686  * } @endcode
0687  */
0688 template <typename Protocol, typename Executor,
0689     typename Iterator, typename ConnectCondition>
0690 Iterator connect(basic_socket<Protocol, Executor>& s,
0691     Iterator begin, Iterator end, ConnectCondition connect_condition,
0692     boost::system::error_code& ec,
0693     constraint_t<
0694       is_connect_condition<ConnectCondition, Iterator>::value
0695     > = 0);
0696 
0697 /*@}*/
0698 
0699 /**
0700  * @defgroup async_connect boost::asio::async_connect
0701  *
0702  * @brief The @c async_connect function is a composed asynchronous operation
0703  * that establishes a socket connection by trying each endpoint in a sequence.
0704  */
0705 /*@{*/
0706 
0707 /// Asynchronously establishes a socket connection by trying each endpoint in a
0708 /// sequence.
0709 /**
0710  * This function attempts to connect a socket to one of a sequence of
0711  * endpoints. It does this by repeated calls to the socket's @c async_connect
0712  * member function, once for each endpoint in the sequence, until a connection
0713  * is successfully established. It is an initiating function for an @ref
0714  * asynchronous_operation, and always returns immediately.
0715  *
0716  * @param s The socket to be connected. If the socket is already open, it will
0717  * be closed.
0718  *
0719  * @param endpoints A sequence of endpoints.
0720  *
0721  * @param token The @ref completion_token that will be used to produce a
0722  * completion handler, which will be called when the connect completes.
0723  * Potential completion tokens include @ref use_future, @ref use_awaitable,
0724  * @ref yield_context, or a function object with the correct completion
0725  * signature. The function signature of the completion handler must be:
0726  * @code void handler(
0727  *   // Result of operation. if the sequence is empty, set to
0728  *   // boost::asio::error::not_found. Otherwise, contains the
0729  *   // error from the last connection attempt.
0730  *   const boost::system::error_code& error,
0731  *
0732  *   // On success, the successfully connected endpoint.
0733  *   // Otherwise, a default-constructed endpoint.
0734  *   const typename Protocol::endpoint& endpoint
0735  * ); @endcode
0736  * Regardless of whether the asynchronous operation completes immediately or
0737  * not, the completion handler will not be invoked from within this function.
0738  * On immediate completion, invocation of the handler will be performed in a
0739  * manner equivalent to using boost::asio::async_immediate().
0740  *
0741  * @par Completion Signature
0742  * @code void(boost::system::error_code, typename Protocol::endpoint) @endcode
0743  *
0744  * @par Example
0745  * @code tcp::resolver r(my_context);
0746  * tcp::resolver::query q("host", "service");
0747  * tcp::socket s(my_context);
0748  *
0749  * // ...
0750  *
0751  * r.async_resolve(q, resolve_handler);
0752  *
0753  * // ...
0754  *
0755  * void resolve_handler(
0756  *     const boost::system::error_code& ec,
0757  *     tcp::resolver::results_type results)
0758  * {
0759  *   if (!ec)
0760  *   {
0761  *     boost::asio::async_connect(s, results, connect_handler);
0762  *   }
0763  * }
0764  *
0765  * // ...
0766  *
0767  * void connect_handler(
0768  *     const boost::system::error_code& ec,
0769  *     const tcp::endpoint& endpoint)
0770  * {
0771  *   // ...
0772  * } @endcode
0773  *
0774  * @par Per-Operation Cancellation
0775  * This asynchronous operation supports cancellation for the following
0776  * boost::asio::cancellation_type values:
0777  *
0778  * @li @c cancellation_type::terminal
0779  *
0780  * @li @c cancellation_type::partial
0781  *
0782  * if they are also supported by the socket's @c async_connect operation.
0783  */
0784 template <typename Protocol, typename Executor, typename EndpointSequence,
0785     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0786       typename Protocol::endpoint)) RangeConnectToken
0787         = default_completion_token_t<Executor>>
0788 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0789     const EndpointSequence& endpoints,
0790     RangeConnectToken&& token = default_completion_token_t<Executor>(),
0791     constraint_t<
0792       is_endpoint_sequence<EndpointSequence>::value
0793     > = 0,
0794     constraint_t<
0795       !is_connect_condition<RangeConnectToken,
0796         decltype(declval<const EndpointSequence&>().begin())>::value
0797     > = 0)
0798   -> decltype(
0799     async_initiate<RangeConnectToken,
0800       void (boost::system::error_code, typename Protocol::endpoint)>(
0801         declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
0802         token, endpoints, declval<detail::default_connect_condition>()))
0803 {
0804   return async_initiate<RangeConnectToken,
0805     void (boost::system::error_code, typename Protocol::endpoint)>(
0806       detail::initiate_async_range_connect<Protocol, Executor>(s),
0807       token, endpoints, detail::default_connect_condition());
0808 }
0809 
0810 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0811 /// (Deprecated: Use range overload.) Asynchronously establishes a socket
0812 /// connection by trying each endpoint in a sequence.
0813 /**
0814  * This function attempts to connect a socket to one of a sequence of
0815  * endpoints. It does this by repeated calls to the socket's @c async_connect
0816  * member function, once for each endpoint in the sequence, until a connection
0817  * is successfully established. It is an initiating function for an @ref
0818  * asynchronous_operation, and always returns immediately.
0819  *
0820  * @param s The socket to be connected. If the socket is already open, it will
0821  * be closed.
0822  *
0823  * @param begin An iterator pointing to the start of a sequence of endpoints.
0824  *
0825  * @param token The @ref completion_token that will be used to produce a
0826  * completion handler, which will be called when the connect completes.
0827  * Potential completion tokens include @ref use_future, @ref use_awaitable,
0828  * @ref yield_context, or a function object with the correct completion
0829  * signature. The function signature of the completion handler must be:
0830  * @code void handler(
0831  *   // Result of operation. if the sequence is empty, set to
0832  *   // boost::asio::error::not_found. Otherwise, contains the
0833  *   // error from the last connection attempt.
0834  *   const boost::system::error_code& error,
0835  *
0836  *   // On success, an iterator denoting the successfully
0837  *   // connected endpoint. Otherwise, the end iterator.
0838  *   Iterator iterator
0839  * ); @endcode
0840  * Regardless of whether the asynchronous operation completes immediately or
0841  * not, the completion handler will not be invoked from within this function.
0842  * On immediate completion, invocation of the handler will be performed in a
0843  * manner equivalent to using boost::asio::async_immediate().
0844  *
0845  * @par Completion Signature
0846  * @code void(boost::system::error_code, Iterator) @endcode
0847  *
0848  * @note This overload assumes that a default constructed object of type @c
0849  * Iterator represents the end of the sequence. This is a valid assumption for
0850  * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
0851  *
0852  * @par Per-Operation Cancellation
0853  * This asynchronous operation supports cancellation for the following
0854  * boost::asio::cancellation_type values:
0855  *
0856  * @li @c cancellation_type::terminal
0857  *
0858  * @li @c cancellation_type::partial
0859  *
0860  * if they are also supported by the socket's @c async_connect operation.
0861  */
0862 template <typename Protocol, typename Executor, typename Iterator,
0863     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0864       Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
0865 inline auto async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0866     IteratorConnectToken&& token = default_completion_token_t<Executor>(),
0867     constraint_t<
0868       !is_endpoint_sequence<Iterator>::value
0869     > = 0,
0870     constraint_t<
0871       !is_same<Iterator, decay_t<IteratorConnectToken>>::value
0872     > = 0,
0873     constraint_t<
0874       !is_connect_condition<IteratorConnectToken, Iterator>::value
0875     > = 0)
0876   -> decltype(
0877     async_initiate<IteratorConnectToken,
0878       void (boost::system::error_code, Iterator)>(
0879         declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
0880         token, begin, Iterator(),
0881         declval<detail::default_connect_condition>()))
0882 {
0883   return async_initiate<IteratorConnectToken,
0884     void (boost::system::error_code, Iterator)>(
0885       detail::initiate_async_iterator_connect<Protocol, Executor>(s),
0886       token, begin, Iterator(), detail::default_connect_condition());
0887 }
0888 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
0889 
0890 /// Asynchronously establishes a socket connection by trying each endpoint in a
0891 /// sequence.
0892 /**
0893  * This function attempts to connect a socket to one of a sequence of
0894  * endpoints. It does this by repeated calls to the socket's @c async_connect
0895  * member function, once for each endpoint in the sequence, until a connection
0896  * is successfully established. It is an initiating function for an @ref
0897  * asynchronous_operation, and always returns immediately.
0898  *
0899  * @param s The socket to be connected. If the socket is already open, it will
0900  * be closed.
0901  *
0902  * @param begin An iterator pointing to the start of a sequence of endpoints.
0903  *
0904  * @param end An iterator pointing to the end of a sequence of endpoints.
0905  *
0906  * @param token The @ref completion_token that will be used to produce a
0907  * completion handler, which will be called when the connect completes.
0908  * Potential completion tokens include @ref use_future, @ref use_awaitable,
0909  * @ref yield_context, or a function object with the correct completion
0910  * signature. The function signature of the completion handler must be:
0911  * @code void handler(
0912  *   // Result of operation. if the sequence is empty, set to
0913  *   // boost::asio::error::not_found. Otherwise, contains the
0914  *   // error from the last connection attempt.
0915  *   const boost::system::error_code& error,
0916  *
0917  *   // On success, an iterator denoting the successfully
0918  *   // connected endpoint. Otherwise, the end iterator.
0919  *   Iterator iterator
0920  * ); @endcode
0921  * Regardless of whether the asynchronous operation completes immediately or
0922  * not, the completion handler will not be invoked from within this function.
0923  * On immediate completion, invocation of the handler will be performed in a
0924  * manner equivalent to using boost::asio::async_immediate().
0925  *
0926  * @par Completion Signature
0927  * @code void(boost::system::error_code, Iterator) @endcode
0928  *
0929  * @par Example
0930  * @code std::vector<tcp::endpoint> endpoints = ...;
0931  * tcp::socket s(my_context);
0932  * boost::asio::async_connect(s,
0933  *     endpoints.begin(), endpoints.end(),
0934  *     connect_handler);
0935  *
0936  * // ...
0937  *
0938  * void connect_handler(
0939  *     const boost::system::error_code& ec,
0940  *     std::vector<tcp::endpoint>::iterator i)
0941  * {
0942  *   // ...
0943  * } @endcode
0944  *
0945  * @par Per-Operation Cancellation
0946  * This asynchronous operation supports cancellation for the following
0947  * boost::asio::cancellation_type values:
0948  *
0949  * @li @c cancellation_type::terminal
0950  *
0951  * @li @c cancellation_type::partial
0952  *
0953  * if they are also supported by the socket's @c async_connect operation.
0954  */
0955 template <typename Protocol, typename Executor, typename Iterator,
0956     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0957       Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
0958 inline auto async_connect(
0959     basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
0960     IteratorConnectToken&& token = default_completion_token_t<Executor>(),
0961     constraint_t<
0962       !is_connect_condition<IteratorConnectToken, Iterator>::value
0963     > = 0)
0964   -> decltype(
0965     async_initiate<IteratorConnectToken,
0966       void (boost::system::error_code, Iterator)>(
0967         declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
0968         token, begin, end, declval<detail::default_connect_condition>()))
0969 {
0970   return async_initiate<IteratorConnectToken,
0971     void (boost::system::error_code, Iterator)>(
0972       detail::initiate_async_iterator_connect<Protocol, Executor>(s),
0973       token, begin, end, detail::default_connect_condition());
0974 }
0975 
0976 /// Asynchronously establishes a socket connection by trying each endpoint in a
0977 /// sequence.
0978 /**
0979  * This function attempts to connect a socket to one of a sequence of
0980  * endpoints. It does this by repeated calls to the socket's @c async_connect
0981  * member function, once for each endpoint in the sequence, until a connection
0982  * is successfully established. It is an initiating function for an @ref
0983  * asynchronous_operation, and always returns immediately.
0984  *
0985  * @param s The socket to be connected. If the socket is already open, it will
0986  * be closed.
0987  *
0988  * @param endpoints A sequence of endpoints.
0989  *
0990  * @param connect_condition A function object that is called prior to each
0991  * connection attempt. The signature of the function object must be:
0992  * @code bool connect_condition(
0993  *     const boost::system::error_code& ec,
0994  *     const typename Protocol::endpoint& next); @endcode
0995  * The @c ec parameter contains the result from the most recent connect
0996  * operation. Before the first connection attempt, @c ec is always set to
0997  * indicate success. The @c next parameter is the next endpoint to be tried.
0998  * The function object should return true if the next endpoint should be tried,
0999  * and false if it should be skipped.
1000  *
1001  * @param token The @ref completion_token that will be used to produce a
1002  * completion handler, which will be called when the connect completes.
1003  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1004  * @ref yield_context, or a function object with the correct completion
1005  * signature. The function signature of the completion handler must be:
1006  * @code void handler(
1007  *   // Result of operation. if the sequence is empty, set to
1008  *   // boost::asio::error::not_found. Otherwise, contains the
1009  *   // error from the last connection attempt.
1010  *   const boost::system::error_code& error,
1011  *
1012  *   // On success, an iterator denoting the successfully
1013  *   // connected endpoint. Otherwise, the end iterator.
1014  *   Iterator iterator
1015  * ); @endcode
1016  * Regardless of whether the asynchronous operation completes immediately or
1017  * not, the completion handler will not be invoked from within this function.
1018  * On immediate completion, invocation of the handler will be performed in a
1019  * manner equivalent to using boost::asio::async_immediate().
1020  *
1021  * @par Completion Signature
1022  * @code void(boost::system::error_code, typename Protocol::endpoint) @endcode
1023  *
1024  * @par Example
1025  * The following connect condition function object can be used to output
1026  * information about the individual connection attempts:
1027  * @code struct my_connect_condition
1028  * {
1029  *   bool operator()(
1030  *       const boost::system::error_code& ec,
1031  *       const::tcp::endpoint& next)
1032  *   {
1033  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
1034  *     std::cout << "Trying: " << next << std::endl;
1035  *     return true;
1036  *   }
1037  * }; @endcode
1038  * It would be used with the boost::asio::connect function as follows:
1039  * @code tcp::resolver r(my_context);
1040  * tcp::resolver::query q("host", "service");
1041  * tcp::socket s(my_context);
1042  *
1043  * // ...
1044  *
1045  * r.async_resolve(q, resolve_handler);
1046  *
1047  * // ...
1048  *
1049  * void resolve_handler(
1050  *     const boost::system::error_code& ec,
1051  *     tcp::resolver::results_type results)
1052  * {
1053  *   if (!ec)
1054  *   {
1055  *     boost::asio::async_connect(s, results,
1056  *         my_connect_condition(),
1057  *         connect_handler);
1058  *   }
1059  * }
1060  *
1061  * // ...
1062  *
1063  * void connect_handler(
1064  *     const boost::system::error_code& ec,
1065  *     const tcp::endpoint& endpoint)
1066  * {
1067  *   if (ec)
1068  *   {
1069  *     // An error occurred.
1070  *   }
1071  *   else
1072  *   {
1073  *     std::cout << "Connected to: " << endpoint << std::endl;
1074  *   }
1075  * } @endcode
1076  *
1077  * @par Per-Operation Cancellation
1078  * This asynchronous operation supports cancellation for the following
1079  * boost::asio::cancellation_type values:
1080  *
1081  * @li @c cancellation_type::terminal
1082  *
1083  * @li @c cancellation_type::partial
1084  *
1085  * if they are also supported by the socket's @c async_connect operation.
1086  */
1087 template <typename Protocol, typename Executor,
1088     typename EndpointSequence, typename ConnectCondition,
1089     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1090       typename Protocol::endpoint)) RangeConnectToken
1091         = default_completion_token_t<Executor>>
1092 inline auto async_connect(basic_socket<Protocol, Executor>& s,
1093     const EndpointSequence& endpoints, ConnectCondition connect_condition,
1094     RangeConnectToken&& token = default_completion_token_t<Executor>(),
1095     constraint_t<
1096       is_endpoint_sequence<EndpointSequence>::value
1097     > = 0,
1098     constraint_t<
1099       is_connect_condition<ConnectCondition,
1100         decltype(declval<const EndpointSequence&>().begin())>::value
1101     > = 0)
1102   -> decltype(
1103     async_initiate<RangeConnectToken,
1104       void (boost::system::error_code, typename Protocol::endpoint)>(
1105         declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
1106         token, endpoints, connect_condition))
1107 {
1108   return async_initiate<RangeConnectToken,
1109     void (boost::system::error_code, typename Protocol::endpoint)>(
1110       detail::initiate_async_range_connect<Protocol, Executor>(s),
1111       token, endpoints, connect_condition);
1112 }
1113 
1114 #if !defined(BOOST_ASIO_NO_DEPRECATED)
1115 /// (Deprecated: Use range overload.) Asynchronously establishes a socket
1116 /// connection by trying each endpoint in a sequence.
1117 /**
1118  * This function attempts to connect a socket to one of a sequence of
1119  * endpoints. It does this by repeated calls to the socket's @c async_connect
1120  * member function, once for each endpoint in the sequence, until a connection
1121  * is successfully established. It is an initiating function for an @ref
1122  * asynchronous_operation, and always returns immediately.
1123  *
1124  * @param s The socket to be connected. If the socket is already open, it will
1125  * be closed.
1126  *
1127  * @param begin An iterator pointing to the start of a sequence of endpoints.
1128  *
1129  * @param connect_condition A function object that is called prior to each
1130  * connection attempt. The signature of the function object must be:
1131  * @code bool connect_condition(
1132  *     const boost::system::error_code& ec,
1133  *     const typename Protocol::endpoint& next); @endcode
1134  * The @c ec parameter contains the result from the most recent connect
1135  * operation. Before the first connection attempt, @c ec is always set to
1136  * indicate success. The @c next parameter is the next endpoint to be tried.
1137  * The function object should return true if the next endpoint should be tried,
1138  * and false if it should be skipped.
1139  *
1140  * @param token The @ref completion_token that will be used to produce a
1141  * completion handler, which will be called when the connect completes.
1142  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1143  * @ref yield_context, or a function object with the correct completion
1144  * signature. The function signature of the completion handler must be:
1145  * @code void handler(
1146  *   // Result of operation. if the sequence is empty, set to
1147  *   // boost::asio::error::not_found. Otherwise, contains the
1148  *   // error from the last connection attempt.
1149  *   const boost::system::error_code& error,
1150  *
1151  *   // On success, an iterator denoting the successfully
1152  *   // connected endpoint. Otherwise, the end iterator.
1153  *   Iterator iterator
1154  * ); @endcode
1155  * Regardless of whether the asynchronous operation completes immediately or
1156  * not, the completion handler will not be invoked from within this function.
1157  * On immediate completion, invocation of the handler will be performed in a
1158  * manner equivalent to using boost::asio::async_immediate().
1159  *
1160  * @par Completion Signature
1161  * @code void(boost::system::error_code, Iterator) @endcode
1162  *
1163  * @note This overload assumes that a default constructed object of type @c
1164  * Iterator represents the end of the sequence. This is a valid assumption for
1165  * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
1166  *
1167  * @par Per-Operation Cancellation
1168  * This asynchronous operation supports cancellation for the following
1169  * boost::asio::cancellation_type values:
1170  *
1171  * @li @c cancellation_type::terminal
1172  *
1173  * @li @c cancellation_type::partial
1174  *
1175  * if they are also supported by the socket's @c async_connect operation.
1176  */
1177 template <typename Protocol, typename Executor,
1178     typename Iterator, typename ConnectCondition,
1179     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1180       Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
1181 inline auto async_connect(basic_socket<Protocol, Executor>& s,
1182     Iterator begin, ConnectCondition connect_condition,
1183     IteratorConnectToken&& token = default_completion_token_t<Executor>(),
1184     constraint_t<
1185       !is_endpoint_sequence<Iterator>::value
1186     > = 0,
1187     constraint_t<
1188       is_connect_condition<ConnectCondition, Iterator>::value
1189     > = 0)
1190   -> decltype(
1191     async_initiate<IteratorConnectToken,
1192       void (boost::system::error_code, Iterator)>(
1193         declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
1194         token, begin, Iterator(), connect_condition))
1195 {
1196   return async_initiate<IteratorConnectToken,
1197     void (boost::system::error_code, Iterator)>(
1198       detail::initiate_async_iterator_connect<Protocol, Executor>(s),
1199       token, begin, Iterator(), connect_condition);
1200 }
1201 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
1202 
1203 /// Asynchronously establishes a socket connection by trying each endpoint in a
1204 /// sequence.
1205 /**
1206  * This function attempts to connect a socket to one of a sequence of
1207  * endpoints. It does this by repeated calls to the socket's @c async_connect
1208  * member function, once for each endpoint in the sequence, until a connection
1209  * is successfully established. It is an initiating function for an @ref
1210  * asynchronous_operation, and always returns immediately.
1211  *
1212  * @param s The socket to be connected. If the socket is already open, it will
1213  * be closed.
1214  *
1215  * @param begin An iterator pointing to the start of a sequence of endpoints.
1216  *
1217  * @param end An iterator pointing to the end of a sequence of endpoints.
1218  *
1219  * @param connect_condition A function object that is called prior to each
1220  * connection attempt. The signature of the function object must be:
1221  * @code bool connect_condition(
1222  *     const boost::system::error_code& ec,
1223  *     const typename Protocol::endpoint& next); @endcode
1224  * The @c ec parameter contains the result from the most recent connect
1225  * operation. Before the first connection attempt, @c ec is always set to
1226  * indicate success. The @c next parameter is the next endpoint to be tried.
1227  * The function object should return true if the next endpoint should be tried,
1228  * and false if it should be skipped.
1229  *
1230  * @param token The @ref completion_token that will be used to produce a
1231  * completion handler, which will be called when the connect completes.
1232  * Potential completion tokens include @ref use_future, @ref use_awaitable,
1233  * @ref yield_context, or a function object with the correct completion
1234  * signature. The function signature of the completion handler must be:
1235  * @code void handler(
1236  *   // Result of operation. if the sequence is empty, set to
1237  *   // boost::asio::error::not_found. Otherwise, contains the
1238  *   // error from the last connection attempt.
1239  *   const boost::system::error_code& error,
1240  *
1241  *   // On success, an iterator denoting the successfully
1242  *   // connected endpoint. Otherwise, the end iterator.
1243  *   Iterator iterator
1244  * ); @endcode
1245  * Regardless of whether the asynchronous operation completes immediately or
1246  * not, the completion handler will not be invoked from within this function.
1247  * On immediate completion, invocation of the handler will be performed in a
1248  * manner equivalent to using boost::asio::async_immediate().
1249  *
1250  * @par Completion Signature
1251  * @code void(boost::system::error_code, Iterator) @endcode
1252  *
1253  * @par Example
1254  * The following connect condition function object can be used to output
1255  * information about the individual connection attempts:
1256  * @code struct my_connect_condition
1257  * {
1258  *   bool operator()(
1259  *       const boost::system::error_code& ec,
1260  *       const::tcp::endpoint& next)
1261  *   {
1262  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
1263  *     std::cout << "Trying: " << next << std::endl;
1264  *     return true;
1265  *   }
1266  * }; @endcode
1267  * It would be used with the boost::asio::connect function as follows:
1268  * @code tcp::resolver r(my_context);
1269  * tcp::resolver::query q("host", "service");
1270  * tcp::socket s(my_context);
1271  *
1272  * // ...
1273  *
1274  * r.async_resolve(q, resolve_handler);
1275  *
1276  * // ...
1277  *
1278  * void resolve_handler(
1279  *     const boost::system::error_code& ec,
1280  *     tcp::resolver::iterator i)
1281  * {
1282  *   if (!ec)
1283  *   {
1284  *     tcp::resolver::iterator end;
1285  *     boost::asio::async_connect(s, i, end,
1286  *         my_connect_condition(),
1287  *         connect_handler);
1288  *   }
1289  * }
1290  *
1291  * // ...
1292  *
1293  * void connect_handler(
1294  *     const boost::system::error_code& ec,
1295  *     tcp::resolver::iterator i)
1296  * {
1297  *   if (ec)
1298  *   {
1299  *     // An error occurred.
1300  *   }
1301  *   else
1302  *   {
1303  *     std::cout << "Connected to: " << i->endpoint() << std::endl;
1304  *   }
1305  * } @endcode
1306  *
1307  * @par Per-Operation Cancellation
1308  * This asynchronous operation supports cancellation for the following
1309  * boost::asio::cancellation_type values:
1310  *
1311  * @li @c cancellation_type::terminal
1312  *
1313  * @li @c cancellation_type::partial
1314  *
1315  * if they are also supported by the socket's @c async_connect operation.
1316  */
1317 template <typename Protocol, typename Executor,
1318     typename Iterator, typename ConnectCondition,
1319     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1320       Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
1321 inline auto async_connect(basic_socket<Protocol, Executor>& s,
1322     Iterator begin, Iterator end, ConnectCondition connect_condition,
1323     IteratorConnectToken&& token = default_completion_token_t<Executor>(),
1324     constraint_t<
1325       is_connect_condition<ConnectCondition, Iterator>::value
1326     > = 0)
1327   -> decltype(
1328     async_initiate<IteratorConnectToken,
1329       void (boost::system::error_code, Iterator)>(
1330         declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
1331         token, begin, end, connect_condition))
1332 {
1333   return async_initiate<IteratorConnectToken,
1334     void (boost::system::error_code, Iterator)>(
1335       detail::initiate_async_iterator_connect<Protocol, Executor>(s),
1336       token, begin, end, connect_condition);
1337 }
1338 
1339 /*@}*/
1340 
1341 } // namespace asio
1342 } // namespace boost
1343 
1344 #include <boost/asio/detail/pop_options.hpp>
1345 
1346 #include <boost/asio/impl/connect.hpp>
1347 
1348 #endif // BOOST_ASIO_CONNECT_HPP