Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:23:48

0001 //
0002 // connect.hpp
0003 // ~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2025 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 /// Establishes a socket connection by trying each endpoint in a sequence.
0203 /**
0204  * This function attempts to connect a socket to one of a sequence of
0205  * endpoints. It does this by repeated calls to the socket's @c connect member
0206  * function, once for each endpoint in the sequence, until a connection is
0207  * successfully established.
0208  *
0209  * @param s The socket to be connected. If the socket is already open, it will
0210  * be closed.
0211  *
0212  * @param begin An iterator pointing to the start of a sequence of endpoints.
0213  *
0214  * @param end An iterator pointing to the end of a sequence of endpoints.
0215  *
0216  * @returns An iterator denoting the successfully connected endpoint.
0217  *
0218  * @throws boost::system::system_error Thrown on failure. If the sequence is
0219  * empty, the associated @c error_code is boost::asio::error::not_found.
0220  * Otherwise, contains the error from the last connection attempt.
0221  *
0222  * @par Example
0223  * @code tcp::resolver r(my_context);
0224  * tcp::resolver::query q("host", "service");
0225  * tcp::resolver::results_type e = r.resolve(q);
0226  * tcp::socket s(my_context);
0227  * boost::asio::connect(s, e.begin(), e.end()); @endcode
0228  */
0229 template <typename Protocol, typename Executor, typename Iterator>
0230 Iterator connect(basic_socket<Protocol, Executor>& s,
0231     Iterator begin, Iterator end);
0232 
0233 /// Establishes a socket connection by trying each endpoint in a sequence.
0234 /**
0235  * This function attempts to connect a socket to one of a sequence of
0236  * endpoints. It does this by repeated calls to the socket's @c connect member
0237  * function, once for each endpoint in the sequence, until a connection is
0238  * successfully established.
0239  *
0240  * @param s The socket to be connected. If the socket is already open, it will
0241  * be closed.
0242  *
0243  * @param begin An iterator pointing to the start of a sequence of endpoints.
0244  *
0245  * @param end An iterator pointing to the end of a sequence of endpoints.
0246  *
0247  * @param ec Set to indicate what error occurred, if any. If the sequence is
0248  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0249  * from the last connection attempt.
0250  *
0251  * @returns On success, an iterator denoting the successfully connected
0252  * endpoint. Otherwise, the end iterator.
0253  *
0254  * @par Example
0255  * @code tcp::resolver r(my_context);
0256  * tcp::resolver::query q("host", "service");
0257  * tcp::resolver::results_type e = r.resolve(q);
0258  * tcp::socket s(my_context);
0259  * boost::system::error_code ec;
0260  * boost::asio::connect(s, e.begin(), e.end(), ec);
0261  * if (ec)
0262  * {
0263  *   // An error occurred.
0264  * } @endcode
0265  */
0266 template <typename Protocol, typename Executor, typename Iterator>
0267 Iterator connect(basic_socket<Protocol, Executor>& s,
0268     Iterator begin, Iterator end, boost::system::error_code& ec);
0269 
0270 /// Establishes a socket connection by trying each endpoint in a sequence.
0271 /**
0272  * This function attempts to connect a socket to one of a sequence of
0273  * endpoints. It does this by repeated calls to the socket's @c connect member
0274  * function, once for each endpoint in the sequence, until a connection is
0275  * successfully established.
0276  *
0277  * @param s The socket to be connected. If the socket is already open, it will
0278  * be closed.
0279  *
0280  * @param endpoints A sequence of endpoints.
0281  *
0282  * @param connect_condition A function object that is called prior to each
0283  * connection attempt. The signature of the function object must be:
0284  * @code bool connect_condition(
0285  *     const boost::system::error_code& ec,
0286  *     const typename Protocol::endpoint& next); @endcode
0287  * The @c ec parameter contains the result from the most recent connect
0288  * operation. Before the first connection attempt, @c ec is always set to
0289  * indicate success. The @c next parameter is the next endpoint to be tried.
0290  * The function object should return true if the next endpoint should be tried,
0291  * and false if it should be skipped.
0292  *
0293  * @returns The successfully connected endpoint.
0294  *
0295  * @throws boost::system::system_error Thrown on failure. If the sequence is
0296  * empty, the associated @c error_code is boost::asio::error::not_found.
0297  * Otherwise, contains the error from the last connection attempt.
0298  *
0299  * @par Example
0300  * The following connect condition function object can be used to output
0301  * information about the individual connection attempts:
0302  * @code struct my_connect_condition
0303  * {
0304  *   bool operator()(
0305  *       const boost::system::error_code& ec,
0306  *       const::tcp::endpoint& next)
0307  *   {
0308  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0309  *     std::cout << "Trying: " << next << std::endl;
0310  *     return true;
0311  *   }
0312  * }; @endcode
0313  * It would be used with the boost::asio::connect function as follows:
0314  * @code tcp::resolver r(my_context);
0315  * tcp::resolver::query q("host", "service");
0316  * tcp::socket s(my_context);
0317  * tcp::endpoint e = boost::asio::connect(s,
0318  *     r.resolve(q), my_connect_condition());
0319  * std::cout << "Connected to: " << e << std::endl; @endcode
0320  */
0321 template <typename Protocol, typename Executor,
0322     typename EndpointSequence, typename ConnectCondition>
0323 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0324     const EndpointSequence& endpoints, ConnectCondition connect_condition,
0325     constraint_t<
0326       is_endpoint_sequence<EndpointSequence>::value
0327     > = 0,
0328     constraint_t<
0329       is_connect_condition<ConnectCondition,
0330         decltype(declval<const EndpointSequence&>().begin())>::value
0331     > = 0);
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  * @param ec Set to indicate what error occurred, if any. If the sequence is
0357  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0358  * from the last connection attempt.
0359  *
0360  * @returns On success, the successfully connected endpoint. Otherwise, a
0361  * default-constructed endpoint.
0362  *
0363  * @par Example
0364  * The following connect condition function object can be used to output
0365  * information about the individual connection attempts:
0366  * @code struct my_connect_condition
0367  * {
0368  *   bool operator()(
0369  *       const boost::system::error_code& ec,
0370  *       const::tcp::endpoint& next)
0371  *   {
0372  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0373  *     std::cout << "Trying: " << next << std::endl;
0374  *     return true;
0375  *   }
0376  * }; @endcode
0377  * It would be used with the boost::asio::connect function as follows:
0378  * @code tcp::resolver r(my_context);
0379  * tcp::resolver::query q("host", "service");
0380  * tcp::socket s(my_context);
0381  * boost::system::error_code ec;
0382  * tcp::endpoint e = boost::asio::connect(s,
0383  *     r.resolve(q), my_connect_condition(), ec);
0384  * if (ec)
0385  * {
0386  *   // An error occurred.
0387  * }
0388  * else
0389  * {
0390  *   std::cout << "Connected to: " << e << std::endl;
0391  * } @endcode
0392  */
0393 template <typename Protocol, typename Executor,
0394     typename EndpointSequence, typename ConnectCondition>
0395 typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
0396     const EndpointSequence& endpoints, ConnectCondition connect_condition,
0397     boost::system::error_code& ec,
0398     constraint_t<
0399       is_endpoint_sequence<EndpointSequence>::value
0400     > = 0,
0401     constraint_t<
0402       is_connect_condition<ConnectCondition,
0403         decltype(declval<const EndpointSequence&>().begin())>::value
0404     > = 0);
0405 
0406 /// Establishes a socket connection by trying each endpoint in a sequence.
0407 /**
0408  * This function attempts to connect a socket to one of a sequence of
0409  * endpoints. It does this by repeated calls to the socket's @c connect member
0410  * function, once for each endpoint in the sequence, until a connection is
0411  * successfully established.
0412  *
0413  * @param s The socket to be connected. If the socket is already open, it will
0414  * be closed.
0415  *
0416  * @param begin An iterator pointing to the start of a sequence of endpoints.
0417  *
0418  * @param end An iterator pointing to the end of a sequence of endpoints.
0419  *
0420  * @param connect_condition A function object that is called prior to each
0421  * connection attempt. The signature of the function object must be:
0422  * @code bool connect_condition(
0423  *     const boost::system::error_code& ec,
0424  *     const typename Protocol::endpoint& next); @endcode
0425  * The @c ec parameter contains the result from the most recent connect
0426  * operation. Before the first connection attempt, @c ec is always set to
0427  * indicate success. The @c next parameter is the next endpoint to be tried.
0428  * The function object should return true if the next endpoint should be tried,
0429  * and false if it should be skipped.
0430  *
0431  * @returns An iterator denoting the successfully connected endpoint.
0432  *
0433  * @throws boost::system::system_error Thrown on failure. If the sequence is
0434  * empty, the associated @c error_code is boost::asio::error::not_found.
0435  * Otherwise, contains the error from the last connection attempt.
0436  *
0437  * @par Example
0438  * The following connect condition function object can be used to output
0439  * information about the individual connection attempts:
0440  * @code struct my_connect_condition
0441  * {
0442  *   bool operator()(
0443  *       const boost::system::error_code& ec,
0444  *       const::tcp::endpoint& next)
0445  *   {
0446  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0447  *     std::cout << "Trying: " << next << std::endl;
0448  *     return true;
0449  *   }
0450  * }; @endcode
0451  * It would be used with the boost::asio::connect function as follows:
0452  * @code tcp::resolver r(my_context);
0453  * tcp::resolver::query q("host", "service");
0454  * tcp::resolver::results_type e = r.resolve(q);
0455  * tcp::socket s(my_context);
0456  * tcp::resolver::results_type::iterator i = boost::asio::connect(
0457  *     s, e.begin(), e.end(), my_connect_condition());
0458  * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
0459  */
0460 template <typename Protocol, typename Executor,
0461     typename Iterator, typename ConnectCondition>
0462 Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
0463     Iterator end, ConnectCondition connect_condition,
0464     constraint_t<
0465       is_connect_condition<ConnectCondition, Iterator>::value
0466     > = 0);
0467 
0468 /// Establishes a socket connection by trying each endpoint in a sequence.
0469 /**
0470  * This function attempts to connect a socket to one of a sequence of
0471  * endpoints. It does this by repeated calls to the socket's @c connect member
0472  * function, once for each endpoint in the sequence, until a connection is
0473  * successfully established.
0474  *
0475  * @param s The socket to be connected. If the socket is already open, it will
0476  * be closed.
0477  *
0478  * @param begin An iterator pointing to the start of a sequence of endpoints.
0479  *
0480  * @param end An iterator pointing to the end of a sequence of endpoints.
0481  *
0482  * @param connect_condition A function object that is called prior to each
0483  * connection attempt. The signature of the function object must be:
0484  * @code bool connect_condition(
0485  *     const boost::system::error_code& ec,
0486  *     const typename Protocol::endpoint& next); @endcode
0487  * The @c ec parameter contains the result from the most recent connect
0488  * operation. Before the first connection attempt, @c ec is always set to
0489  * indicate success. The @c next parameter is the next endpoint to be tried.
0490  * The function object should return true if the next endpoint should be tried,
0491  * and false if it should be skipped.
0492  *
0493  * @param ec Set to indicate what error occurred, if any. If the sequence is
0494  * empty, set to boost::asio::error::not_found. Otherwise, contains the error
0495  * from the last connection attempt.
0496  *
0497  * @returns On success, an iterator denoting the successfully connected
0498  * endpoint. Otherwise, the end iterator.
0499  *
0500  * @par Example
0501  * The following connect condition function object can be used to output
0502  * information about the individual connection attempts:
0503  * @code struct my_connect_condition
0504  * {
0505  *   bool operator()(
0506  *       const boost::system::error_code& ec,
0507  *       const::tcp::endpoint& next)
0508  *   {
0509  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0510  *     std::cout << "Trying: " << next << std::endl;
0511  *     return true;
0512  *   }
0513  * }; @endcode
0514  * It would be used with the boost::asio::connect function as follows:
0515  * @code tcp::resolver r(my_context);
0516  * tcp::resolver::query q("host", "service");
0517  * tcp::resolver::results_type e = r.resolve(q);
0518  * tcp::socket s(my_context);
0519  * boost::system::error_code ec;
0520  * tcp::resolver::results_type::iterator i = boost::asio::connect(
0521  *     s, e.begin(), e.end(), my_connect_condition());
0522  * if (ec)
0523  * {
0524  *   // An error occurred.
0525  * }
0526  * else
0527  * {
0528  *   std::cout << "Connected to: " << i->endpoint() << std::endl;
0529  * } @endcode
0530  */
0531 template <typename Protocol, typename Executor,
0532     typename Iterator, typename ConnectCondition>
0533 Iterator connect(basic_socket<Protocol, Executor>& s,
0534     Iterator begin, Iterator end, ConnectCondition connect_condition,
0535     boost::system::error_code& ec,
0536     constraint_t<
0537       is_connect_condition<ConnectCondition, Iterator>::value
0538     > = 0);
0539 
0540 /*@}*/
0541 
0542 /**
0543  * @defgroup async_connect boost::asio::async_connect
0544  *
0545  * @brief The @c async_connect function is a composed asynchronous operation
0546  * that establishes a socket connection by trying each endpoint in a sequence.
0547  */
0548 /*@{*/
0549 
0550 /// Asynchronously establishes a socket connection by trying each endpoint in a
0551 /// sequence.
0552 /**
0553  * This function attempts to connect a socket to one of a sequence of
0554  * endpoints. It does this by repeated calls to the socket's @c async_connect
0555  * member function, once for each endpoint in the sequence, until a connection
0556  * is successfully established. It is an initiating function for an @ref
0557  * asynchronous_operation, and always returns immediately.
0558  *
0559  * @param s The socket to be connected. If the socket is already open, it will
0560  * be closed.
0561  *
0562  * @param endpoints A sequence of endpoints.
0563  *
0564  * @param token The @ref completion_token that will be used to produce a
0565  * completion handler, which will be called when the connect completes.
0566  * Potential completion tokens include @ref use_future, @ref use_awaitable,
0567  * @ref yield_context, or a function object with the correct completion
0568  * signature. The function signature of the completion handler must be:
0569  * @code void handler(
0570  *   // Result of operation. if the sequence is empty, set to
0571  *   // boost::asio::error::not_found. Otherwise, contains the
0572  *   // error from the last connection attempt.
0573  *   const boost::system::error_code& error,
0574  *
0575  *   // On success, the successfully connected endpoint.
0576  *   // Otherwise, a default-constructed endpoint.
0577  *   const typename Protocol::endpoint& endpoint
0578  * ); @endcode
0579  * Regardless of whether the asynchronous operation completes immediately or
0580  * not, the completion handler will not be invoked from within this function.
0581  * On immediate completion, invocation of the handler will be performed in a
0582  * manner equivalent to using boost::asio::async_immediate().
0583  *
0584  * @par Completion Signature
0585  * @code void(boost::system::error_code, typename Protocol::endpoint) @endcode
0586  *
0587  * @par Example
0588  * @code tcp::resolver r(my_context);
0589  * tcp::resolver::query q("host", "service");
0590  * tcp::socket s(my_context);
0591  *
0592  * // ...
0593  *
0594  * r.async_resolve(q, resolve_handler);
0595  *
0596  * // ...
0597  *
0598  * void resolve_handler(
0599  *     const boost::system::error_code& ec,
0600  *     tcp::resolver::results_type results)
0601  * {
0602  *   if (!ec)
0603  *   {
0604  *     boost::asio::async_connect(s, results, connect_handler);
0605  *   }
0606  * }
0607  *
0608  * // ...
0609  *
0610  * void connect_handler(
0611  *     const boost::system::error_code& ec,
0612  *     const tcp::endpoint& endpoint)
0613  * {
0614  *   // ...
0615  * } @endcode
0616  *
0617  * @par Per-Operation Cancellation
0618  * This asynchronous operation supports cancellation for the following
0619  * boost::asio::cancellation_type values:
0620  *
0621  * @li @c cancellation_type::terminal
0622  *
0623  * @li @c cancellation_type::partial
0624  *
0625  * if they are also supported by the socket's @c async_connect operation.
0626  */
0627 template <typename Protocol, typename Executor, typename EndpointSequence,
0628     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0629       typename Protocol::endpoint)) RangeConnectToken
0630         = default_completion_token_t<Executor>>
0631 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0632     const EndpointSequence& endpoints,
0633     RangeConnectToken&& token = default_completion_token_t<Executor>(),
0634     constraint_t<
0635       is_endpoint_sequence<EndpointSequence>::value
0636     > = 0,
0637     constraint_t<
0638       !is_connect_condition<RangeConnectToken,
0639         decltype(declval<const EndpointSequence&>().begin())>::value
0640     > = 0)
0641   -> decltype(
0642     async_initiate<RangeConnectToken,
0643       void (boost::system::error_code, typename Protocol::endpoint)>(
0644         declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
0645         token, endpoints, declval<detail::default_connect_condition>()))
0646 {
0647   return async_initiate<RangeConnectToken,
0648     void (boost::system::error_code, typename Protocol::endpoint)>(
0649       detail::initiate_async_range_connect<Protocol, Executor>(s),
0650       token, endpoints, detail::default_connect_condition());
0651 }
0652 
0653 /// Asynchronously establishes a socket connection by trying each endpoint in a
0654 /// sequence.
0655 /**
0656  * This function attempts to connect a socket to one of a sequence of
0657  * endpoints. It does this by repeated calls to the socket's @c async_connect
0658  * member function, once for each endpoint in the sequence, until a connection
0659  * is successfully established. It is an initiating function for an @ref
0660  * asynchronous_operation, and always returns immediately.
0661  *
0662  * @param s The socket to be connected. If the socket is already open, it will
0663  * be closed.
0664  *
0665  * @param begin An iterator pointing to the start of a sequence of endpoints.
0666  *
0667  * @param end An iterator pointing to the end of a sequence of endpoints.
0668  *
0669  * @param token The @ref completion_token that will be used to produce a
0670  * completion handler, which will be called when the connect completes.
0671  * Potential completion tokens include @ref use_future, @ref use_awaitable,
0672  * @ref yield_context, or a function object with the correct completion
0673  * signature. The function signature of the completion handler must be:
0674  * @code void handler(
0675  *   // Result of operation. if the sequence is empty, set to
0676  *   // boost::asio::error::not_found. Otherwise, contains the
0677  *   // error from the last connection attempt.
0678  *   const boost::system::error_code& error,
0679  *
0680  *   // On success, an iterator denoting the successfully
0681  *   // connected endpoint. Otherwise, the end iterator.
0682  *   Iterator iterator
0683  * ); @endcode
0684  * Regardless of whether the asynchronous operation completes immediately or
0685  * not, the completion handler will not be invoked from within this function.
0686  * On immediate completion, invocation of the handler will be performed in a
0687  * manner equivalent to using boost::asio::async_immediate().
0688  *
0689  * @par Completion Signature
0690  * @code void(boost::system::error_code, Iterator) @endcode
0691  *
0692  * @par Example
0693  * @code std::vector<tcp::endpoint> endpoints = ...;
0694  * tcp::socket s(my_context);
0695  * boost::asio::async_connect(s,
0696  *     endpoints.begin(), endpoints.end(),
0697  *     connect_handler);
0698  *
0699  * // ...
0700  *
0701  * void connect_handler(
0702  *     const boost::system::error_code& ec,
0703  *     std::vector<tcp::endpoint>::iterator i)
0704  * {
0705  *   // ...
0706  * } @endcode
0707  *
0708  * @par Per-Operation Cancellation
0709  * This asynchronous operation supports cancellation for the following
0710  * boost::asio::cancellation_type values:
0711  *
0712  * @li @c cancellation_type::terminal
0713  *
0714  * @li @c cancellation_type::partial
0715  *
0716  * if they are also supported by the socket's @c async_connect operation.
0717  */
0718 template <typename Protocol, typename Executor, typename Iterator,
0719     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0720       Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
0721 inline auto async_connect(
0722     basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
0723     IteratorConnectToken&& token = default_completion_token_t<Executor>(),
0724     constraint_t<
0725       !is_connect_condition<IteratorConnectToken, Iterator>::value
0726     > = 0)
0727   -> decltype(
0728     async_initiate<IteratorConnectToken,
0729       void (boost::system::error_code, Iterator)>(
0730         declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
0731         token, begin, end, declval<detail::default_connect_condition>()))
0732 {
0733   return async_initiate<IteratorConnectToken,
0734     void (boost::system::error_code, Iterator)>(
0735       detail::initiate_async_iterator_connect<Protocol, Executor>(s),
0736       token, begin, end, detail::default_connect_condition());
0737 }
0738 
0739 /// Asynchronously establishes a socket connection by trying each endpoint in a
0740 /// sequence.
0741 /**
0742  * This function attempts to connect a socket to one of a sequence of
0743  * endpoints. It does this by repeated calls to the socket's @c async_connect
0744  * member function, once for each endpoint in the sequence, until a connection
0745  * is successfully established. It is an initiating function for an @ref
0746  * asynchronous_operation, and always returns immediately.
0747  *
0748  * @param s The socket to be connected. If the socket is already open, it will
0749  * be closed.
0750  *
0751  * @param endpoints A sequence of endpoints.
0752  *
0753  * @param connect_condition A function object that is called prior to each
0754  * connection attempt. The signature of the function object must be:
0755  * @code bool connect_condition(
0756  *     const boost::system::error_code& ec,
0757  *     const typename Protocol::endpoint& next); @endcode
0758  * The @c ec parameter contains the result from the most recent connect
0759  * operation. Before the first connection attempt, @c ec is always set to
0760  * indicate success. The @c next parameter is the next endpoint to be tried.
0761  * The function object should return true if the next endpoint should be tried,
0762  * and false if it should be skipped.
0763  *
0764  * @param token The @ref completion_token that will be used to produce a
0765  * completion handler, which will be called when the connect completes.
0766  * Potential completion tokens include @ref use_future, @ref use_awaitable,
0767  * @ref yield_context, or a function object with the correct completion
0768  * signature. The function signature of the completion handler must be:
0769  * @code void handler(
0770  *   // Result of operation. if the sequence is empty, set to
0771  *   // boost::asio::error::not_found. Otherwise, contains the
0772  *   // error from the last connection attempt.
0773  *   const boost::system::error_code& error,
0774  *
0775  *   // On success, an iterator denoting the successfully
0776  *   // connected endpoint. Otherwise, the end iterator.
0777  *   Iterator iterator
0778  * ); @endcode
0779  * Regardless of whether the asynchronous operation completes immediately or
0780  * not, the completion handler will not be invoked from within this function.
0781  * On immediate completion, invocation of the handler will be performed in a
0782  * manner equivalent to using boost::asio::async_immediate().
0783  *
0784  * @par Completion Signature
0785  * @code void(boost::system::error_code, typename Protocol::endpoint) @endcode
0786  *
0787  * @par Example
0788  * The following connect condition function object can be used to output
0789  * information about the individual connection attempts:
0790  * @code struct my_connect_condition
0791  * {
0792  *   bool operator()(
0793  *       const boost::system::error_code& ec,
0794  *       const::tcp::endpoint& next)
0795  *   {
0796  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0797  *     std::cout << "Trying: " << next << std::endl;
0798  *     return true;
0799  *   }
0800  * }; @endcode
0801  * It would be used with the boost::asio::connect function as follows:
0802  * @code tcp::resolver r(my_context);
0803  * tcp::resolver::query q("host", "service");
0804  * tcp::socket s(my_context);
0805  *
0806  * // ...
0807  *
0808  * r.async_resolve(q, resolve_handler);
0809  *
0810  * // ...
0811  *
0812  * void resolve_handler(
0813  *     const boost::system::error_code& ec,
0814  *     tcp::resolver::results_type results)
0815  * {
0816  *   if (!ec)
0817  *   {
0818  *     boost::asio::async_connect(s, results,
0819  *         my_connect_condition(),
0820  *         connect_handler);
0821  *   }
0822  * }
0823  *
0824  * // ...
0825  *
0826  * void connect_handler(
0827  *     const boost::system::error_code& ec,
0828  *     const tcp::endpoint& endpoint)
0829  * {
0830  *   if (ec)
0831  *   {
0832  *     // An error occurred.
0833  *   }
0834  *   else
0835  *   {
0836  *     std::cout << "Connected to: " << endpoint << std::endl;
0837  *   }
0838  * } @endcode
0839  *
0840  * @par Per-Operation Cancellation
0841  * This asynchronous operation supports cancellation for the following
0842  * boost::asio::cancellation_type values:
0843  *
0844  * @li @c cancellation_type::terminal
0845  *
0846  * @li @c cancellation_type::partial
0847  *
0848  * if they are also supported by the socket's @c async_connect operation.
0849  */
0850 template <typename Protocol, typename Executor,
0851     typename EndpointSequence, typename ConnectCondition,
0852     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0853       typename Protocol::endpoint)) RangeConnectToken
0854         = default_completion_token_t<Executor>>
0855 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0856     const EndpointSequence& endpoints, ConnectCondition connect_condition,
0857     RangeConnectToken&& token = default_completion_token_t<Executor>(),
0858     constraint_t<
0859       is_endpoint_sequence<EndpointSequence>::value
0860     > = 0,
0861     constraint_t<
0862       is_connect_condition<ConnectCondition,
0863         decltype(declval<const EndpointSequence&>().begin())>::value
0864     > = 0)
0865   -> decltype(
0866     async_initiate<RangeConnectToken,
0867       void (boost::system::error_code, typename Protocol::endpoint)>(
0868         declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
0869         token, endpoints, connect_condition))
0870 {
0871   return async_initiate<RangeConnectToken,
0872     void (boost::system::error_code, typename Protocol::endpoint)>(
0873       detail::initiate_async_range_connect<Protocol, Executor>(s),
0874       token, endpoints, connect_condition);
0875 }
0876 
0877 /// Asynchronously establishes a socket connection by trying each endpoint in a
0878 /// sequence.
0879 /**
0880  * This function attempts to connect a socket to one of a sequence of
0881  * endpoints. It does this by repeated calls to the socket's @c async_connect
0882  * member function, once for each endpoint in the sequence, until a connection
0883  * is successfully established. It is an initiating function for an @ref
0884  * asynchronous_operation, and always returns immediately.
0885  *
0886  * @param s The socket to be connected. If the socket is already open, it will
0887  * be closed.
0888  *
0889  * @param begin An iterator pointing to the start of a sequence of endpoints.
0890  *
0891  * @param end An iterator pointing to the end of a sequence of endpoints.
0892  *
0893  * @param connect_condition A function object that is called prior to each
0894  * connection attempt. The signature of the function object must be:
0895  * @code bool connect_condition(
0896  *     const boost::system::error_code& ec,
0897  *     const typename Protocol::endpoint& next); @endcode
0898  * The @c ec parameter contains the result from the most recent connect
0899  * operation. Before the first connection attempt, @c ec is always set to
0900  * indicate success. The @c next parameter is the next endpoint to be tried.
0901  * The function object should return true if the next endpoint should be tried,
0902  * and false if it should be skipped.
0903  *
0904  * @param token The @ref completion_token that will be used to produce a
0905  * completion handler, which will be called when the connect completes.
0906  * Potential completion tokens include @ref use_future, @ref use_awaitable,
0907  * @ref yield_context, or a function object with the correct completion
0908  * signature. The function signature of the completion handler must be:
0909  * @code void handler(
0910  *   // Result of operation. if the sequence is empty, set to
0911  *   // boost::asio::error::not_found. Otherwise, contains the
0912  *   // error from the last connection attempt.
0913  *   const boost::system::error_code& error,
0914  *
0915  *   // On success, an iterator denoting the successfully
0916  *   // connected endpoint. Otherwise, the end iterator.
0917  *   Iterator iterator
0918  * ); @endcode
0919  * Regardless of whether the asynchronous operation completes immediately or
0920  * not, the completion handler will not be invoked from within this function.
0921  * On immediate completion, invocation of the handler will be performed in a
0922  * manner equivalent to using boost::asio::async_immediate().
0923  *
0924  * @par Completion Signature
0925  * @code void(boost::system::error_code, Iterator) @endcode
0926  *
0927  * @par Example
0928  * The following connect condition function object can be used to output
0929  * information about the individual connection attempts:
0930  * @code struct my_connect_condition
0931  * {
0932  *   bool operator()(
0933  *       const boost::system::error_code& ec,
0934  *       const::tcp::endpoint& next)
0935  *   {
0936  *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
0937  *     std::cout << "Trying: " << next << std::endl;
0938  *     return true;
0939  *   }
0940  * }; @endcode
0941  * It would be used with the boost::asio::connect function as follows:
0942  * @code tcp::resolver r(my_context);
0943  * tcp::resolver::query q("host", "service");
0944  * tcp::socket s(my_context);
0945  *
0946  * // ...
0947  *
0948  * r.async_resolve(q, resolve_handler);
0949  *
0950  * // ...
0951  *
0952  * void resolve_handler(
0953  *     const boost::system::error_code& ec,
0954  *     tcp::resolver::iterator i)
0955  * {
0956  *   if (!ec)
0957  *   {
0958  *     tcp::resolver::iterator end;
0959  *     boost::asio::async_connect(s, i, end,
0960  *         my_connect_condition(),
0961  *         connect_handler);
0962  *   }
0963  * }
0964  *
0965  * // ...
0966  *
0967  * void connect_handler(
0968  *     const boost::system::error_code& ec,
0969  *     tcp::resolver::iterator i)
0970  * {
0971  *   if (ec)
0972  *   {
0973  *     // An error occurred.
0974  *   }
0975  *   else
0976  *   {
0977  *     std::cout << "Connected to: " << i->endpoint() << std::endl;
0978  *   }
0979  * } @endcode
0980  *
0981  * @par Per-Operation Cancellation
0982  * This asynchronous operation supports cancellation for the following
0983  * boost::asio::cancellation_type values:
0984  *
0985  * @li @c cancellation_type::terminal
0986  *
0987  * @li @c cancellation_type::partial
0988  *
0989  * if they are also supported by the socket's @c async_connect operation.
0990  */
0991 template <typename Protocol, typename Executor,
0992     typename Iterator, typename ConnectCondition,
0993     BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0994       Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
0995 inline auto async_connect(basic_socket<Protocol, Executor>& s,
0996     Iterator begin, Iterator end, ConnectCondition connect_condition,
0997     IteratorConnectToken&& token = default_completion_token_t<Executor>(),
0998     constraint_t<
0999       is_connect_condition<ConnectCondition, Iterator>::value
1000     > = 0)
1001   -> decltype(
1002     async_initiate<IteratorConnectToken,
1003       void (boost::system::error_code, Iterator)>(
1004         declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
1005         token, begin, end, connect_condition))
1006 {
1007   return async_initiate<IteratorConnectToken,
1008     void (boost::system::error_code, Iterator)>(
1009       detail::initiate_async_iterator_connect<Protocol, Executor>(s),
1010       token, begin, end, connect_condition);
1011 }
1012 
1013 /*@}*/
1014 
1015 } // namespace asio
1016 } // namespace boost
1017 
1018 #include <boost/asio/detail/pop_options.hpp>
1019 
1020 #include <boost/asio/impl/connect.hpp>
1021 
1022 #endif // BOOST_ASIO_CONNECT_HPP