Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:00

0001 //
0002 // ip/basic_resolver.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 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_IP_BASIC_RESOLVER_HPP
0012 #define BOOST_ASIO_IP_BASIC_RESOLVER_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 <string>
0020 #include <utility>
0021 #include <boost/asio/any_io_executor.hpp>
0022 #include <boost/asio/async_result.hpp>
0023 #include <boost/asio/detail/handler_type_requirements.hpp>
0024 #include <boost/asio/detail/io_object_impl.hpp>
0025 #include <boost/asio/detail/non_const_lvalue.hpp>
0026 #include <boost/asio/detail/string_view.hpp>
0027 #include <boost/asio/detail/throw_error.hpp>
0028 #include <boost/asio/error.hpp>
0029 #include <boost/asio/execution_context.hpp>
0030 #include <boost/asio/ip/basic_resolver_iterator.hpp>
0031 #include <boost/asio/ip/basic_resolver_query.hpp>
0032 #include <boost/asio/ip/basic_resolver_results.hpp>
0033 #include <boost/asio/ip/resolver_base.hpp>
0034 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
0035 # include <boost/asio/detail/winrt_resolver_service.hpp>
0036 #else
0037 # include <boost/asio/detail/resolver_service.hpp>
0038 #endif
0039 
0040 #include <boost/asio/detail/push_options.hpp>
0041 
0042 namespace boost {
0043 namespace asio {
0044 namespace ip {
0045 
0046 #if !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
0047 #define BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL
0048 
0049 // Forward declaration with defaulted arguments.
0050 template <typename InternetProtocol, typename Executor = any_io_executor>
0051 class basic_resolver;
0052 
0053 #endif // !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
0054 
0055 /// Provides endpoint resolution functionality.
0056 /**
0057  * The basic_resolver class template provides the ability to resolve a query
0058  * to a list of endpoints.
0059  *
0060  * @par Thread Safety
0061  * @e Distinct @e objects: Safe.@n
0062  * @e Shared @e objects: Unsafe.
0063  */
0064 template <typename InternetProtocol, typename Executor>
0065 class basic_resolver
0066   : public resolver_base
0067 {
0068 private:
0069   class initiate_async_resolve;
0070 
0071 public:
0072   /// The type of the executor associated with the object.
0073   typedef Executor executor_type;
0074 
0075   /// Rebinds the resolver type to another executor.
0076   template <typename Executor1>
0077   struct rebind_executor
0078   {
0079     /// The resolver type when rebound to the specified executor.
0080     typedef basic_resolver<InternetProtocol, Executor1> other;
0081   };
0082 
0083   /// The protocol type.
0084   typedef InternetProtocol protocol_type;
0085 
0086   /// The endpoint type.
0087   typedef typename InternetProtocol::endpoint endpoint_type;
0088 
0089 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0090   /// (Deprecated.) The query type.
0091   typedef basic_resolver_query<InternetProtocol> query;
0092 
0093   /// (Deprecated.) The iterator type.
0094   typedef basic_resolver_iterator<InternetProtocol> iterator;
0095 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
0096 
0097   /// The results type.
0098   typedef basic_resolver_results<InternetProtocol> results_type;
0099 
0100   /// Construct with executor.
0101   /**
0102    * This constructor creates a basic_resolver.
0103    *
0104    * @param ex The I/O executor that the resolver will use, by default, to
0105    * dispatch handlers for any asynchronous operations performed on the
0106    * resolver.
0107    */
0108   explicit basic_resolver(const executor_type& ex)
0109     : impl_(0, ex)
0110   {
0111   }
0112 
0113   /// Construct with execution context.
0114   /**
0115    * This constructor creates a basic_resolver.
0116    *
0117    * @param context An execution context which provides the I/O executor that
0118    * the resolver will use, by default, to dispatch handlers for any
0119    * asynchronous operations performed on the resolver.
0120    */
0121   template <typename ExecutionContext>
0122   explicit basic_resolver(ExecutionContext& context,
0123       constraint_t<
0124         is_convertible<ExecutionContext&, execution_context&>::value
0125       > = 0)
0126     : impl_(0, 0, context)
0127   {
0128   }
0129 
0130   /// Move-construct a basic_resolver from another.
0131   /**
0132    * This constructor moves a resolver from one object to another.
0133    *
0134    * @param other The other basic_resolver object from which the move will
0135    * occur.
0136    *
0137    * @note Following the move, the moved-from object is in the same state as if
0138    * constructed using the @c basic_resolver(const executor_type&) constructor.
0139    */
0140   basic_resolver(basic_resolver&& other)
0141     : impl_(std::move(other.impl_))
0142   {
0143   }
0144 
0145   // All resolvers have access to each other's implementations.
0146   template <typename InternetProtocol1, typename Executor1>
0147   friend class basic_resolver;
0148 
0149   /// Move-construct a basic_resolver from another.
0150   /**
0151    * This constructor moves a resolver from one object to another.
0152    *
0153    * @param other The other basic_resolver object from which the move will
0154    * occur.
0155    *
0156    * @note Following the move, the moved-from object is in the same state as if
0157    * constructed using the @c basic_resolver(const executor_type&) constructor.
0158    */
0159   template <typename Executor1>
0160   basic_resolver(basic_resolver<InternetProtocol, Executor1>&& other,
0161       constraint_t<
0162           is_convertible<Executor1, Executor>::value
0163       > = 0)
0164     : impl_(std::move(other.impl_))
0165   {
0166   }
0167 
0168   /// Move-assign a basic_resolver from another.
0169   /**
0170    * This assignment operator moves a resolver from one object to another.
0171    * Cancels any outstanding asynchronous operations associated with the target
0172    * object.
0173    *
0174    * @param other The other basic_resolver object from which the move will
0175    * occur.
0176    *
0177    * @note Following the move, the moved-from object is in the same state as if
0178    * constructed using the @c basic_resolver(const executor_type&) constructor.
0179    */
0180   basic_resolver& operator=(basic_resolver&& other)
0181   {
0182     impl_ = std::move(other.impl_);
0183     return *this;
0184   }
0185 
0186   /// Move-assign a basic_resolver from another.
0187   /**
0188    * This assignment operator moves a resolver from one object to another.
0189    * Cancels any outstanding asynchronous operations associated with the target
0190    * object.
0191    *
0192    * @param other The other basic_resolver object from which the move will
0193    * occur.
0194    *
0195    * @note Following the move, the moved-from object is in the same state as if
0196    * constructed using the @c basic_resolver(const executor_type&) constructor.
0197    */
0198   template <typename Executor1>
0199   constraint_t<
0200     is_convertible<Executor1, Executor>::value,
0201     basic_resolver&
0202   > operator=(basic_resolver<InternetProtocol, Executor1>&& other)
0203   {
0204     basic_resolver tmp(std::move(other));
0205     impl_ = std::move(tmp.impl_);
0206     return *this;
0207   }
0208 
0209   /// Destroys the resolver.
0210   /**
0211    * This function destroys the resolver, cancelling any outstanding
0212    * asynchronous wait operations associated with the resolver as if by calling
0213    * @c cancel.
0214    */
0215   ~basic_resolver()
0216   {
0217   }
0218 
0219   /// Get the executor associated with the object.
0220   executor_type get_executor() noexcept
0221   {
0222     return impl_.get_executor();
0223   }
0224 
0225   /// Cancel any asynchronous operations that are waiting on the resolver.
0226   /**
0227    * This function forces the completion of any pending asynchronous
0228    * operations on the host resolver. The handler for each cancelled operation
0229    * will be invoked with the boost::asio::error::operation_aborted error code.
0230    */
0231   void cancel()
0232   {
0233     return impl_.get_service().cancel(impl_.get_implementation());
0234   }
0235 
0236 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0237   /// (Deprecated: Use overload with separate host and service parameters.)
0238   /// Perform forward resolution of a query to a list of entries.
0239   /**
0240    * This function is used to resolve a query into a list of endpoint entries.
0241    *
0242    * @param q A query object that determines what endpoints will be returned.
0243    *
0244    * @returns A range object representing the list of endpoint entries. A
0245    * successful call to this function is guaranteed to return a non-empty
0246    * range.
0247    *
0248    * @throws boost::system::system_error Thrown on failure.
0249    */
0250   results_type resolve(const query& q)
0251   {
0252     boost::system::error_code ec;
0253     results_type r = impl_.get_service().resolve(
0254         impl_.get_implementation(), q, ec);
0255     boost::asio::detail::throw_error(ec, "resolve");
0256     return r;
0257   }
0258 
0259   /// (Deprecated: Use overload with separate host and service parameters.)
0260   /// Perform forward resolution of a query to a list of entries.
0261   /**
0262    * This function is used to resolve a query into a list of endpoint entries.
0263    *
0264    * @param q A query object that determines what endpoints will be returned.
0265    *
0266    * @param ec Set to indicate what error occurred, if any.
0267    *
0268    * @returns A range object representing the list of endpoint entries. An
0269    * empty range is returned if an error occurs. A successful call to this
0270    * function is guaranteed to return a non-empty range.
0271    */
0272   results_type resolve(const query& q, boost::system::error_code& ec)
0273   {
0274     return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
0275   }
0276 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
0277 
0278   /// Perform forward resolution of a query to a list of entries.
0279   /**
0280    * This function is used to resolve host and service names into a list of
0281    * endpoint entries.
0282    *
0283    * @param host A string identifying a location. May be a descriptive name or
0284    * a numeric address string. If an empty string and the passive flag has been
0285    * specified, the resolved endpoints are suitable for local service binding.
0286    * If an empty string and passive is not specified, the resolved endpoints
0287    * will use the loopback address.
0288    *
0289    * @param service A string identifying the requested service. This may be a
0290    * descriptive name or a numeric string corresponding to a port number. May
0291    * be an empty string, in which case all resolved endpoints will have a port
0292    * number of 0.
0293    *
0294    * @returns A range object representing the list of endpoint entries. A
0295    * successful call to this function is guaranteed to return a non-empty
0296    * range.
0297    *
0298    * @throws boost::system::system_error Thrown on failure.
0299    *
0300    * @note On POSIX systems, host names may be locally defined in the file
0301    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0302    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0303    * resolution is performed using DNS. Operating systems may use additional
0304    * locations when resolving host names (such as NETBIOS names on Windows).
0305    *
0306    * On POSIX systems, service names are typically defined in the file
0307    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0308    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0309    * may use additional locations when resolving service names.
0310    */
0311   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
0312       BOOST_ASIO_STRING_VIEW_PARAM service)
0313   {
0314     return resolve(host, service, resolver_base::flags());
0315   }
0316 
0317   /// Perform forward resolution of a query to a list of entries.
0318   /**
0319    * This function is used to resolve host and service names into a list of
0320    * endpoint entries.
0321    *
0322    * @param host A string identifying a location. May be a descriptive name or
0323    * a numeric address string. If an empty string and the passive flag has been
0324    * specified, the resolved endpoints are suitable for local service binding.
0325    * If an empty string and passive is not specified, the resolved endpoints
0326    * will use the loopback address.
0327    *
0328    * @param service A string identifying the requested service. This may be a
0329    * descriptive name or a numeric string corresponding to a port number. May
0330    * be an empty string, in which case all resolved endpoints will have a port
0331    * number of 0.
0332    *
0333    * @param ec Set to indicate what error occurred, if any.
0334    *
0335    * @returns A range object representing the list of endpoint entries. An
0336    * empty range is returned if an error occurs. A successful call to this
0337    * function is guaranteed to return a non-empty range.
0338    *
0339    * @note On POSIX systems, host names may be locally defined in the file
0340    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0341    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0342    * resolution is performed using DNS. Operating systems may use additional
0343    * locations when resolving host names (such as NETBIOS names on Windows).
0344    *
0345    * On POSIX systems, service names are typically defined in the file
0346    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0347    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0348    * may use additional locations when resolving service names.
0349    */
0350   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
0351       BOOST_ASIO_STRING_VIEW_PARAM service, boost::system::error_code& ec)
0352   {
0353     return resolve(host, service, resolver_base::flags(), ec);
0354   }
0355 
0356   /// Perform forward resolution of a query to a list of entries.
0357   /**
0358    * This function is used to resolve host and service names into a list of
0359    * endpoint entries.
0360    *
0361    * @param host A string identifying a location. May be a descriptive name or
0362    * a numeric address string. If an empty string and the passive flag has been
0363    * specified, the resolved endpoints are suitable for local service binding.
0364    * If an empty string and passive is not specified, the resolved endpoints
0365    * will use the loopback address.
0366    *
0367    * @param service A string identifying the requested service. This may be a
0368    * descriptive name or a numeric string corresponding to a port number. May
0369    * be an empty string, in which case all resolved endpoints will have a port
0370    * number of 0.
0371    *
0372    * @param resolve_flags A set of flags that determine how name resolution
0373    * should be performed. The default flags are suitable for communication with
0374    * remote hosts. See the @ref resolver_base documentation for the set of
0375    * available flags.
0376    *
0377    * @returns A range object representing the list of endpoint entries. A
0378    * successful call to this function is guaranteed to return a non-empty
0379    * range.
0380    *
0381    * @throws boost::system::system_error Thrown on failure.
0382    *
0383    * @note On POSIX systems, host names may be locally defined in the file
0384    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0385    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0386    * resolution is performed using DNS. Operating systems may use additional
0387    * locations when resolving host names (such as NETBIOS names on Windows).
0388    *
0389    * On POSIX systems, service names are typically defined in the file
0390    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0391    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0392    * may use additional locations when resolving service names.
0393    */
0394   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
0395       BOOST_ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags)
0396   {
0397     boost::system::error_code ec;
0398     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
0399         static_cast<std::string>(service), resolve_flags);
0400     results_type r = impl_.get_service().resolve(
0401         impl_.get_implementation(), q, ec);
0402     boost::asio::detail::throw_error(ec, "resolve");
0403     return r;
0404   }
0405 
0406   /// Perform forward resolution of a query to a list of entries.
0407   /**
0408    * This function is used to resolve host and service names into a list of
0409    * endpoint entries.
0410    *
0411    * @param host A string identifying a location. May be a descriptive name or
0412    * a numeric address string. If an empty string and the passive flag has been
0413    * specified, the resolved endpoints are suitable for local service binding.
0414    * If an empty string and passive is not specified, the resolved endpoints
0415    * will use the loopback address.
0416    *
0417    * @param service A string identifying the requested service. This may be a
0418    * descriptive name or a numeric string corresponding to a port number. May
0419    * be an empty string, in which case all resolved endpoints will have a port
0420    * number of 0.
0421    *
0422    * @param resolve_flags A set of flags that determine how name resolution
0423    * should be performed. The default flags are suitable for communication with
0424    * remote hosts. See the @ref resolver_base documentation for the set of
0425    * available flags.
0426    *
0427    * @param ec Set to indicate what error occurred, if any.
0428    *
0429    * @returns A range object representing the list of endpoint entries. An
0430    * empty range is returned if an error occurs. A successful call to this
0431    * function is guaranteed to return a non-empty range.
0432    *
0433    * @note On POSIX systems, host names may be locally defined in the file
0434    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0435    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0436    * resolution is performed using DNS. Operating systems may use additional
0437    * locations when resolving host names (such as NETBIOS names on Windows).
0438    *
0439    * On POSIX systems, service names are typically defined in the file
0440    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0441    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0442    * may use additional locations when resolving service names.
0443    */
0444   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
0445       BOOST_ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags,
0446       boost::system::error_code& ec)
0447   {
0448     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
0449         static_cast<std::string>(service), resolve_flags);
0450     return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
0451   }
0452 
0453   /// Perform forward resolution of a query to a list of entries.
0454   /**
0455    * This function is used to resolve host and service names into a list of
0456    * endpoint entries.
0457    *
0458    * @param protocol A protocol object, normally representing either the IPv4 or
0459    * IPv6 version of an internet protocol.
0460    *
0461    * @param host A string identifying a location. May be a descriptive name or
0462    * a numeric address string. If an empty string and the passive flag has been
0463    * specified, the resolved endpoints are suitable for local service binding.
0464    * If an empty string and passive is not specified, the resolved endpoints
0465    * will use the loopback address.
0466    *
0467    * @param service A string identifying the requested service. This may be a
0468    * descriptive name or a numeric string corresponding to a port number. May
0469    * be an empty string, in which case all resolved endpoints will have a port
0470    * number of 0.
0471    *
0472    * @returns A range object representing the list of endpoint entries. A
0473    * successful call to this function is guaranteed to return a non-empty
0474    * range.
0475    *
0476    * @throws boost::system::system_error Thrown on failure.
0477    *
0478    * @note On POSIX systems, host names may be locally defined in the file
0479    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0480    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0481    * resolution is performed using DNS. Operating systems may use additional
0482    * locations when resolving host names (such as NETBIOS names on Windows).
0483    *
0484    * On POSIX systems, service names are typically defined in the file
0485    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0486    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0487    * may use additional locations when resolving service names.
0488    */
0489   results_type resolve(const protocol_type& protocol,
0490       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service)
0491   {
0492     return resolve(protocol, host, service, resolver_base::flags());
0493   }
0494 
0495   /// Perform forward resolution of a query to a list of entries.
0496   /**
0497    * This function is used to resolve host and service names into a list of
0498    * endpoint entries.
0499    *
0500    * @param protocol A protocol object, normally representing either the IPv4 or
0501    * IPv6 version of an internet protocol.
0502    *
0503    * @param host A string identifying a location. May be a descriptive name or
0504    * a numeric address string. If an empty string and the passive flag has been
0505    * specified, the resolved endpoints are suitable for local service binding.
0506    * If an empty string and passive is not specified, the resolved endpoints
0507    * will use the loopback address.
0508    *
0509    * @param service A string identifying the requested service. This may be a
0510    * descriptive name or a numeric string corresponding to a port number. May
0511    * be an empty string, in which case all resolved endpoints will have a port
0512    * number of 0.
0513    *
0514    * @param ec Set to indicate what error occurred, if any.
0515    *
0516    * @returns A range object representing the list of endpoint entries. An
0517    * empty range is returned if an error occurs. A successful call to this
0518    * function is guaranteed to return a non-empty range.
0519    *
0520    * @note On POSIX systems, host names may be locally defined in the file
0521    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0522    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0523    * resolution is performed using DNS. Operating systems may use additional
0524    * locations when resolving host names (such as NETBIOS names on Windows).
0525    *
0526    * On POSIX systems, service names are typically defined in the file
0527    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0528    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0529    * may use additional locations when resolving service names.
0530    */
0531   results_type resolve(const protocol_type& protocol,
0532       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
0533       boost::system::error_code& ec)
0534   {
0535     return resolve(protocol, host, service, resolver_base::flags(), ec);
0536   }
0537 
0538   /// Perform forward resolution of a query to a list of entries.
0539   /**
0540    * This function is used to resolve host and service names into a list of
0541    * endpoint entries.
0542    *
0543    * @param protocol A protocol object, normally representing either the IPv4 or
0544    * IPv6 version of an internet protocol.
0545    *
0546    * @param host A string identifying a location. May be a descriptive name or
0547    * a numeric address string. If an empty string and the passive flag has been
0548    * specified, the resolved endpoints are suitable for local service binding.
0549    * If an empty string and passive is not specified, the resolved endpoints
0550    * will use the loopback address.
0551    *
0552    * @param service A string identifying the requested service. This may be a
0553    * descriptive name or a numeric string corresponding to a port number. May
0554    * be an empty string, in which case all resolved endpoints will have a port
0555    * number of 0.
0556    *
0557    * @param resolve_flags A set of flags that determine how name resolution
0558    * should be performed. The default flags are suitable for communication with
0559    * remote hosts. See the @ref resolver_base documentation for the set of
0560    * available flags.
0561    *
0562    * @returns A range object representing the list of endpoint entries. A
0563    * successful call to this function is guaranteed to return a non-empty
0564    * range.
0565    *
0566    * @throws boost::system::system_error Thrown on failure.
0567    *
0568    * @note On POSIX systems, host names may be locally defined in the file
0569    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0570    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0571    * resolution is performed using DNS. Operating systems may use additional
0572    * locations when resolving host names (such as NETBIOS names on Windows).
0573    *
0574    * On POSIX systems, service names are typically defined in the file
0575    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0576    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0577    * may use additional locations when resolving service names.
0578    */
0579   results_type resolve(const protocol_type& protocol,
0580       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
0581       resolver_base::flags resolve_flags)
0582   {
0583     boost::system::error_code ec;
0584     basic_resolver_query<protocol_type> q(
0585         protocol, static_cast<std::string>(host),
0586         static_cast<std::string>(service), resolve_flags);
0587     results_type r = impl_.get_service().resolve(
0588         impl_.get_implementation(), q, ec);
0589     boost::asio::detail::throw_error(ec, "resolve");
0590     return r;
0591   }
0592 
0593   /// Perform forward resolution of a query to a list of entries.
0594   /**
0595    * This function is used to resolve host and service names into a list of
0596    * endpoint entries.
0597    *
0598    * @param protocol A protocol object, normally representing either the IPv4 or
0599    * IPv6 version of an internet protocol.
0600    *
0601    * @param host A string identifying a location. May be a descriptive name or
0602    * a numeric address string. If an empty string and the passive flag has been
0603    * specified, the resolved endpoints are suitable for local service binding.
0604    * If an empty string and passive is not specified, the resolved endpoints
0605    * will use the loopback address.
0606    *
0607    * @param service A string identifying the requested service. This may be a
0608    * descriptive name or a numeric string corresponding to a port number. May
0609    * be an empty string, in which case all resolved endpoints will have a port
0610    * number of 0.
0611    *
0612    * @param resolve_flags A set of flags that determine how name resolution
0613    * should be performed. The default flags are suitable for communication with
0614    * remote hosts. See the @ref resolver_base documentation for the set of
0615    * available flags.
0616    *
0617    * @param ec Set to indicate what error occurred, if any.
0618    *
0619    * @returns A range object representing the list of endpoint entries. An
0620    * empty range is returned if an error occurs. A successful call to this
0621    * function is guaranteed to return a non-empty range.
0622    *
0623    * @note On POSIX systems, host names may be locally defined in the file
0624    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0625    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0626    * resolution is performed using DNS. Operating systems may use additional
0627    * locations when resolving host names (such as NETBIOS names on Windows).
0628    *
0629    * On POSIX systems, service names are typically defined in the file
0630    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0631    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0632    * may use additional locations when resolving service names.
0633    */
0634   results_type resolve(const protocol_type& protocol,
0635       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
0636       resolver_base::flags resolve_flags, boost::system::error_code& ec)
0637   {
0638     basic_resolver_query<protocol_type> q(
0639         protocol, static_cast<std::string>(host),
0640         static_cast<std::string>(service), resolve_flags);
0641     return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
0642   }
0643 
0644 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0645   /// (Deprecated: Use overload with separate host and service parameters.)
0646   /// Asynchronously perform forward resolution of a query to a list of entries.
0647   /**
0648    * This function is used to asynchronously resolve a query into a list of
0649    * endpoint entries. It is an initiating function for an @ref
0650    * asynchronous_operation, and always returns immediately.
0651    *
0652    * @param q A query object that determines what endpoints will be returned.
0653    *
0654    * @param token The @ref completion_token that will be used to produce a
0655    * completion handler, which will be called when the resolve completes.
0656    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0657    * @ref yield_context, or a function object with the correct completion
0658    * signature. The function signature of the completion handler must be:
0659    * @code void handler(
0660    *   const boost::system::error_code& error, // Result of operation.
0661    *   resolver::results_type results // Resolved endpoints as a range.
0662    * ); @endcode
0663    * Regardless of whether the asynchronous operation completes immediately or
0664    * not, the completion handler will not be invoked from within this function.
0665    * On immediate completion, invocation of the handler will be performed in a
0666    * manner equivalent to using boost::asio::post().
0667    *
0668    * A successful resolve operation is guaranteed to pass a non-empty range to
0669    * the handler.
0670    *
0671    * @par Completion Signature
0672    * @code void(boost::system::error_code, results_type) @endcode
0673    */
0674   template <
0675       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0676         results_type)) ResolveToken = default_completion_token_t<executor_type>>
0677   auto async_resolve(const query& q,
0678       ResolveToken&& token = default_completion_token_t<executor_type>())
0679     -> decltype(
0680       boost::asio::async_initiate<ResolveToken,
0681         void (boost::system::error_code, results_type)>(
0682           declval<initiate_async_resolve>(), token, q))
0683   {
0684     return boost::asio::async_initiate<ResolveToken,
0685       void (boost::system::error_code, results_type)>(
0686         initiate_async_resolve(this), token, q);
0687   }
0688 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
0689 
0690   /// Asynchronously perform forward resolution of a query to a list of entries.
0691   /**
0692    * This function is used to resolve host and service names into a list of
0693    * endpoint entries.
0694    *
0695    * @param host A string identifying a location. May be a descriptive name or
0696    * a numeric address string. If an empty string and the passive flag has been
0697    * specified, the resolved endpoints are suitable for local service binding.
0698    * If an empty string and passive is not specified, the resolved endpoints
0699    * will use the loopback address.
0700    *
0701    * @param service A string identifying the requested service. This may be a
0702    * descriptive name or a numeric string corresponding to a port number. May
0703    * be an empty string, in which case all resolved endpoints will have a port
0704    * number of 0.
0705    *
0706    * @param token The @ref completion_token that will be used to produce a
0707    * completion handler, which will be called when the resolve completes.
0708    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0709    * @ref yield_context, or a function object with the correct completion
0710    * signature. The function signature of the completion handler must be:
0711    * @code void handler(
0712    *   const boost::system::error_code& error, // Result of operation.
0713    *   resolver::results_type results // Resolved endpoints as a range.
0714    * ); @endcode
0715    * Regardless of whether the asynchronous operation completes immediately or
0716    * not, the completion handler will not be invoked from within this function.
0717    * On immediate completion, invocation of the handler will be performed in a
0718    * manner equivalent to using boost::asio::post().
0719    *
0720    * A successful resolve operation is guaranteed to pass a non-empty range to
0721    * the handler.
0722    *
0723    * @par Completion Signature
0724    * @code void(boost::system::error_code, results_type) @endcode
0725    *
0726    * @note On POSIX systems, host names may be locally defined in the file
0727    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0728    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0729    * resolution is performed using DNS. Operating systems may use additional
0730    * locations when resolving host names (such as NETBIOS names on Windows).
0731    *
0732    * On POSIX systems, service names are typically defined in the file
0733    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0734    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0735    * may use additional locations when resolving service names.
0736    */
0737   template <
0738       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0739         results_type)) ResolveToken = default_completion_token_t<executor_type>>
0740   auto async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
0741       BOOST_ASIO_STRING_VIEW_PARAM service,
0742       ResolveToken&& token = default_completion_token_t<executor_type>())
0743     -> decltype(
0744       boost::asio::async_initiate<ResolveToken,
0745         void (boost::system::error_code, results_type)>(
0746           declval<initiate_async_resolve>(), token,
0747           declval<basic_resolver_query<protocol_type>&>()))
0748   {
0749     return async_resolve(host, service, resolver_base::flags(),
0750         static_cast<ResolveToken&&>(token));
0751   }
0752 
0753   /// Asynchronously perform forward resolution of a query to a list of entries.
0754   /**
0755    * This function is used to resolve host and service names into a list of
0756    * endpoint entries. It is an initiating function for an @ref
0757    * asynchronous_operation, and always returns immediately.
0758    *
0759    * @param host A string identifying a location. May be a descriptive name or
0760    * a numeric address string. If an empty string and the passive flag has been
0761    * specified, the resolved endpoints are suitable for local service binding.
0762    * If an empty string and passive is not specified, the resolved endpoints
0763    * will use the loopback address.
0764    *
0765    * @param service A string identifying the requested service. This may be a
0766    * descriptive name or a numeric string corresponding to a port number. May
0767    * be an empty string, in which case all resolved endpoints will have a port
0768    * number of 0.
0769    *
0770    * @param resolve_flags A set of flags that determine how name resolution
0771    * should be performed. The default flags are suitable for communication with
0772    * remote hosts. See the @ref resolver_base documentation for the set of
0773    * available flags.
0774    *
0775    * @param token The @ref completion_token that will be used to produce a
0776    * completion handler, which will be called when the resolve completes.
0777    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0778    * @ref yield_context, or a function object with the correct completion
0779    * signature. The function signature of the completion handler must be:
0780    * @code void handler(
0781    *   const boost::system::error_code& error, // Result of operation.
0782    *   resolver::results_type results // Resolved endpoints as a range.
0783    * ); @endcode
0784    * Regardless of whether the asynchronous operation completes immediately or
0785    * not, the completion handler will not be invoked from within this function.
0786    * On immediate completion, invocation of the handler will be performed in a
0787    * manner equivalent to using boost::asio::post().
0788    *
0789    * A successful resolve operation is guaranteed to pass a non-empty range to
0790    * the handler.
0791    *
0792    * @par Completion Signature
0793    * @code void(boost::system::error_code, results_type) @endcode
0794    *
0795    * @note On POSIX systems, host names may be locally defined in the file
0796    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0797    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0798    * resolution is performed using DNS. Operating systems may use additional
0799    * locations when resolving host names (such as NETBIOS names on Windows).
0800    *
0801    * On POSIX systems, service names are typically defined in the file
0802    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0803    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0804    * may use additional locations when resolving service names.
0805    */
0806   template <
0807       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0808         results_type)) ResolveToken = default_completion_token_t<executor_type>>
0809   auto async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
0810       BOOST_ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags,
0811       ResolveToken&& token = default_completion_token_t<executor_type>())
0812     -> decltype(
0813       boost::asio::async_initiate<ResolveToken,
0814         void (boost::system::error_code, results_type)>(
0815           declval<initiate_async_resolve>(), token,
0816           declval<basic_resolver_query<protocol_type>&>()))
0817   {
0818     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
0819         static_cast<std::string>(service), resolve_flags);
0820 
0821     return boost::asio::async_initiate<ResolveToken,
0822       void (boost::system::error_code, results_type)>(
0823         initiate_async_resolve(this), token, q);
0824   }
0825 
0826   /// Asynchronously perform forward resolution of a query to a list of entries.
0827   /**
0828    * This function is used to resolve host and service names into a list of
0829    * endpoint entries. It is an initiating function for an @ref
0830    * asynchronous_operation, and always returns immediately.
0831    *
0832    * @param protocol A protocol object, normally representing either the IPv4 or
0833    * IPv6 version of an internet protocol.
0834    *
0835    * @param host A string identifying a location. May be a descriptive name or
0836    * a numeric address string. If an empty string and the passive flag has been
0837    * specified, the resolved endpoints are suitable for local service binding.
0838    * If an empty string and passive is not specified, the resolved endpoints
0839    * will use the loopback address.
0840    *
0841    * @param service A string identifying the requested service. This may be a
0842    * descriptive name or a numeric string corresponding to a port number. May
0843    * be an empty string, in which case all resolved endpoints will have a port
0844    * number of 0.
0845    *
0846    * @param token The @ref completion_token that will be used to produce a
0847    * completion handler, which will be called when the resolve completes.
0848    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0849    * @ref yield_context, or a function object with the correct completion
0850    * signature. The function signature of the completion handler must be:
0851    * @code void handler(
0852    *   const boost::system::error_code& error, // Result of operation.
0853    *   resolver::results_type results // Resolved endpoints as a range.
0854    * ); @endcode
0855    * Regardless of whether the asynchronous operation completes immediately or
0856    * not, the completion handler will not be invoked from within this function.
0857    * On immediate completion, invocation of the handler will be performed in a
0858    * manner equivalent to using boost::asio::post().
0859    *
0860    * A successful resolve operation is guaranteed to pass a non-empty range to
0861    * the handler.
0862    *
0863    * @par Completion Signature
0864    * @code void(boost::system::error_code, results_type) @endcode
0865    *
0866    * @note On POSIX systems, host names may be locally defined in the file
0867    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0868    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0869    * resolution is performed using DNS. Operating systems may use additional
0870    * locations when resolving host names (such as NETBIOS names on Windows).
0871    *
0872    * On POSIX systems, service names are typically defined in the file
0873    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0874    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0875    * may use additional locations when resolving service names.
0876    */
0877   template <
0878       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0879         results_type)) ResolveToken = default_completion_token_t<executor_type>>
0880   auto async_resolve(const protocol_type& protocol,
0881       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
0882       ResolveToken&& token = default_completion_token_t<executor_type>())
0883     -> decltype(
0884       boost::asio::async_initiate<ResolveToken,
0885         void (boost::system::error_code, results_type)>(
0886           declval<initiate_async_resolve>(), token,
0887           declval<basic_resolver_query<protocol_type>&>()))
0888   {
0889     return async_resolve(protocol, host, service, resolver_base::flags(),
0890         static_cast<ResolveToken&&>(token));
0891   }
0892 
0893   /// Asynchronously perform forward resolution of a query to a list of entries.
0894   /**
0895    * This function is used to resolve host and service names into a list of
0896    * endpoint entries. It is an initiating function for an @ref
0897    * asynchronous_operation, and always returns immediately.
0898    *
0899    * @param protocol A protocol object, normally representing either the IPv4 or
0900    * IPv6 version of an internet protocol.
0901    *
0902    * @param host A string identifying a location. May be a descriptive name or
0903    * a numeric address string. If an empty string and the passive flag has been
0904    * specified, the resolved endpoints are suitable for local service binding.
0905    * If an empty string and passive is not specified, the resolved endpoints
0906    * will use the loopback address.
0907    *
0908    * @param service A string identifying the requested service. This may be a
0909    * descriptive name or a numeric string corresponding to a port number. May
0910    * be an empty string, in which case all resolved endpoints will have a port
0911    * number of 0.
0912    *
0913    * @param resolve_flags A set of flags that determine how name resolution
0914    * should be performed. The default flags are suitable for communication with
0915    * remote hosts. See the @ref resolver_base documentation for the set of
0916    * available flags.
0917    *
0918    * @param token The @ref completion_token that will be used to produce a
0919    * completion handler, which will be called when the resolve completes.
0920    * Potential completion tokens include @ref use_future, @ref use_awaitable,
0921    * @ref yield_context, or a function object with the correct completion
0922    * signature. The function signature of the completion handler must be:
0923    * @code void handler(
0924    *   const boost::system::error_code& error, // Result of operation.
0925    *   resolver::results_type results // Resolved endpoints as a range.
0926    * ); @endcode
0927    * Regardless of whether the asynchronous operation completes immediately or
0928    * not, the completion handler will not be invoked from within this function.
0929    * On immediate completion, invocation of the handler will be performed in a
0930    * manner equivalent to using boost::asio::post().
0931    *
0932    * A successful resolve operation is guaranteed to pass a non-empty range to
0933    * the handler.
0934    *
0935    * @par Completion Signature
0936    * @code void(boost::system::error_code, results_type) @endcode
0937    *
0938    * @note On POSIX systems, host names may be locally defined in the file
0939    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
0940    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
0941    * resolution is performed using DNS. Operating systems may use additional
0942    * locations when resolving host names (such as NETBIOS names on Windows).
0943    *
0944    * On POSIX systems, service names are typically defined in the file
0945    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
0946    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
0947    * may use additional locations when resolving service names.
0948    */
0949   template <
0950       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
0951         results_type)) ResolveToken = default_completion_token_t<executor_type>>
0952   auto async_resolve(const protocol_type& protocol,
0953       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
0954       resolver_base::flags resolve_flags,
0955       ResolveToken&& token = default_completion_token_t<executor_type>())
0956     -> decltype(
0957       boost::asio::async_initiate<ResolveToken,
0958         void (boost::system::error_code, results_type)>(
0959           declval<initiate_async_resolve>(), token,
0960           declval<basic_resolver_query<protocol_type>&>()))
0961   {
0962     basic_resolver_query<protocol_type> q(
0963         protocol, static_cast<std::string>(host),
0964         static_cast<std::string>(service), resolve_flags);
0965 
0966     return boost::asio::async_initiate<ResolveToken,
0967       void (boost::system::error_code, results_type)>(
0968         initiate_async_resolve(this), token, q);
0969   }
0970 
0971   /// Perform reverse resolution of an endpoint to a list of entries.
0972   /**
0973    * This function is used to resolve an endpoint into a list of endpoint
0974    * entries.
0975    *
0976    * @param e An endpoint object that determines what endpoints will be
0977    * returned.
0978    *
0979    * @returns A range object representing the list of endpoint entries. A
0980    * successful call to this function is guaranteed to return a non-empty
0981    * range.
0982    *
0983    * @throws boost::system::system_error Thrown on failure.
0984    */
0985   results_type resolve(const endpoint_type& e)
0986   {
0987     boost::system::error_code ec;
0988     results_type i = impl_.get_service().resolve(
0989         impl_.get_implementation(), e, ec);
0990     boost::asio::detail::throw_error(ec, "resolve");
0991     return i;
0992   }
0993 
0994   /// Perform reverse resolution of an endpoint to a list of entries.
0995   /**
0996    * This function is used to resolve an endpoint into a list of endpoint
0997    * entries.
0998    *
0999    * @param e An endpoint object that determines what endpoints will be
1000    * returned.
1001    *
1002    * @param ec Set to indicate what error occurred, if any.
1003    *
1004    * @returns A range object representing the list of endpoint entries. An
1005    * empty range is returned if an error occurs. A successful call to this
1006    * function is guaranteed to return a non-empty range.
1007    */
1008   results_type resolve(const endpoint_type& e, boost::system::error_code& ec)
1009   {
1010     return impl_.get_service().resolve(impl_.get_implementation(), e, ec);
1011   }
1012 
1013   /// Asynchronously perform reverse resolution of an endpoint to a list of
1014   /// entries.
1015   /**
1016    * This function is used to asynchronously resolve an endpoint into a list of
1017    * endpoint entries. It is an initiating function for an @ref
1018    * asynchronous_operation, and always returns immediately.
1019    *
1020    * @param e An endpoint object that determines what endpoints will be
1021    * returned.
1022    *
1023    * @param token The @ref completion_token that will be used to produce a
1024    * completion handler, which will be called when the resolve completes.
1025    * Potential completion tokens include @ref use_future, @ref use_awaitable,
1026    * @ref yield_context, or a function object with the correct completion
1027    * signature. The function signature of the completion handler must be:
1028    * @code void handler(
1029    *   const boost::system::error_code& error, // Result of operation.
1030    *   resolver::results_type results // Resolved endpoints as a range.
1031    * ); @endcode
1032    * Regardless of whether the asynchronous operation completes immediately or
1033    * not, the completion handler will not be invoked from within this function.
1034    * On immediate completion, invocation of the handler will be performed in a
1035    * manner equivalent to using boost::asio::post().
1036    *
1037    * A successful resolve operation is guaranteed to pass a non-empty range to
1038    * the handler.
1039    *
1040    * @par Completion Signature
1041    * @code void(boost::system::error_code, results_type) @endcode
1042    */
1043   template <
1044       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1045         results_type)) ResolveToken = default_completion_token_t<executor_type>>
1046   auto async_resolve(const endpoint_type& e,
1047       ResolveToken&& token = default_completion_token_t<executor_type>())
1048     -> decltype(
1049       boost::asio::async_initiate<ResolveToken,
1050         void (boost::system::error_code, results_type)>(
1051           declval<initiate_async_resolve>(), token, e))
1052   {
1053     return boost::asio::async_initiate<ResolveToken,
1054       void (boost::system::error_code, results_type)>(
1055         initiate_async_resolve(this), token, e);
1056   }
1057 
1058 private:
1059   // Disallow copying and assignment.
1060   basic_resolver(const basic_resolver&) = delete;
1061   basic_resolver& operator=(const basic_resolver&) = delete;
1062 
1063   class initiate_async_resolve
1064   {
1065   public:
1066     typedef Executor executor_type;
1067 
1068     explicit initiate_async_resolve(basic_resolver* self)
1069       : self_(self)
1070     {
1071     }
1072 
1073     executor_type get_executor() const noexcept
1074     {
1075       return self_->get_executor();
1076     }
1077 
1078     template <typename ResolveHandler, typename Query>
1079     void operator()(ResolveHandler&& handler,
1080         const Query& q) const
1081     {
1082       // If you get an error on the following line it means that your handler
1083       // does not meet the documented type requirements for a ResolveHandler.
1084       BOOST_ASIO_RESOLVE_HANDLER_CHECK(
1085           ResolveHandler, handler, results_type) type_check;
1086 
1087       boost::asio::detail::non_const_lvalue<ResolveHandler> handler2(handler);
1088       self_->impl_.get_service().async_resolve(
1089           self_->impl_.get_implementation(), q,
1090           handler2.value, self_->impl_.get_executor());
1091     }
1092 
1093   private:
1094     basic_resolver* self_;
1095   };
1096 
1097 # if defined(BOOST_ASIO_WINDOWS_RUNTIME)
1098   boost::asio::detail::io_object_impl<
1099     boost::asio::detail::winrt_resolver_service<InternetProtocol>,
1100     Executor> impl_;
1101 # else
1102   boost::asio::detail::io_object_impl<
1103     boost::asio::detail::resolver_service<InternetProtocol>,
1104     Executor> impl_;
1105 # endif
1106 };
1107 
1108 } // namespace ip
1109 } // namespace asio
1110 } // namespace boost
1111 
1112 #include <boost/asio/detail/pop_options.hpp>
1113 
1114 #endif // BOOST_ASIO_IP_BASIC_RESOLVER_HPP