]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/asio/ip/basic_resolver.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / asio / ip / basic_resolver.hpp
index 969d9d8ac3be769f697c3ab1bd8450d6f7133cd2..21e025cb74886989b22ba2e762ffd48e83ec1644 100644 (file)
@@ -2,7 +2,7 @@
 // ip/basic_resolver.hpp
 // ~~~~~~~~~~~~~~~~~~~~~
 //
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 #include <boost/asio/detail/config.hpp>
 #include <string>
 #include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
 #include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
 #include <boost/asio/detail/string_view.hpp>
 #include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.hpp>
 #include <boost/asio/ip/basic_resolver_results.hpp>
 #include <boost/asio/ip/resolver_base.hpp>
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/winrt_resolver_service.hpp>
+#else
+# include <boost/asio/detail/resolver_service.hpp>
+#endif
 
 #if defined(BOOST_ASIO_HAS_MOVE)
 # include <utility>
 #endif // defined(BOOST_ASIO_HAS_MOVE)
 
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/ip/resolver_service.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-#  include <boost/asio/detail/winrt_resolver_service.hpp>
-#  define BOOST_ASIO_SVC_T \
-    boost::asio::detail::winrt_resolver_service<InternetProtocol>
-# else
-#  include <boost/asio/detail/resolver_service.hpp>
-#  define BOOST_ASIO_SVC_T \
-    boost::asio::detail::resolver_service<InternetProtocol>
-# endif
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
 #include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace ip {
 
+#if !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
+#define BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename InternetProtocol, typename Executor = executor>
+class basic_resolver;
+
+#endif // !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
+
 /// Provides endpoint resolution functionality.
 /**
  * The basic_resolver class template provides the ability to resolve a query
@@ -62,15 +64,21 @@ namespace ip {
  * @e Distinct @e objects: Safe.@n
  * @e Shared @e objects: Unsafe.
  */
-template <typename InternetProtocol
-    BOOST_ASIO_SVC_TPARAM_DEF1(= resolver_service<InternetProtocol>)>
+template <typename InternetProtocol, typename Executor>
 class basic_resolver
-  : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
-    public resolver_base
+  : public resolver_base
 {
 public:
   /// The type of the executor associated with the object.
-  typedef io_context::executor_type executor_type;
+  typedef Executor executor_type;
+
+  /// Rebinds the resolver type to another executor.
+  template <typename Executor1>
+  struct rebind_executor
+  {
+    /// The resolver type when rebound to the specified executor.
+    typedef basic_resolver<InternetProtocol, Executor1> other;
+  };
 
   /// The protocol type.
   typedef InternetProtocol protocol_type;
@@ -89,16 +97,33 @@ public:
   /// The results type.
   typedef basic_resolver_results<InternetProtocol> results_type;
 
-  /// Constructor.
+  /// Construct with executor.
   /**
    * This constructor creates a basic_resolver.
    *
-   * @param io_context The io_context object that the resolver will use to
+   * @param ex The I/O executor that the resolver will use, by default, to
    * dispatch handlers for any asynchronous operations performed on the
    * resolver.
    */
-  explicit basic_resolver(boost::asio::io_context& io_context)
-    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  explicit basic_resolver(const executor_type& ex)
+    : impl_(ex)
+  {
+  }
+
+  /// Construct with execution context.
+  /**
+   * This constructor creates a basic_resolver.
+   *
+   * @param context An execution context which provides the I/O executor that
+   * the resolver will use, by default, to dispatch handlers for any
+   * asynchronous operations performed on the resolver.
+   */
+  template <typename ExecutionContext>
+  explicit basic_resolver(ExecutionContext& context,
+      typename enable_if<
+        is_convertible<ExecutionContext&, execution_context&>::value
+      >::type* = 0)
+    : impl_(context)
   {
   }
 
@@ -111,10 +136,10 @@ public:
    * occur.
    *
    * @note Following the move, the moved-from object is in the same state as if
-   * constructed using the @c basic_resolver(io_context&) constructor.
+   * constructed using the @c basic_resolver(const executor_type&) constructor.
    */
   basic_resolver(basic_resolver&& other)
-    : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+    : impl_(std::move(other.impl_))
   {
   }
 
@@ -128,11 +153,11 @@ public:
    * occur.
    *
    * @note Following the move, the moved-from object is in the same state as if
-   * constructed using the @c basic_resolver(io_context&) constructor.
+   * constructed using the @c basic_resolver(const executor_type&) constructor.
    */
   basic_resolver& operator=(basic_resolver&& other)
   {
-    basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+    impl_ = std::move(other.impl_);
     return *this;
   }
 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -147,45 +172,11 @@ public:
   {
   }
 
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-  // These functions are provided by basic_io_object<>.
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
-  /// (Deprecated: Use get_executor().) Get the io_context associated with the
-  /// object.
-  /**
-   * This function may be used to obtain the io_context object that the I/O
-   * object uses to dispatch handlers for asynchronous operations.
-   *
-   * @return A reference to the io_context object that the I/O object will use
-   * to dispatch handlers. Ownership is not transferred to the caller.
-   */
-  boost::asio::io_context& get_io_context()
-  {
-    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
-  }
-
-  /// (Deprecated: Use get_executor().) Get the io_context associated with the
-  /// object.
-  /**
-   * This function may be used to obtain the io_context object that the I/O
-   * object uses to dispatch handlers for asynchronous operations.
-   *
-   * @return A reference to the io_context object that the I/O object will use
-   * to dispatch handlers. Ownership is not transferred to the caller.
-   */
-  boost::asio::io_context& get_io_service()
-  {
-    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
-  }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
   /// Get the executor associated with the object.
   executor_type get_executor() BOOST_ASIO_NOEXCEPT
   {
-    return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+    return impl_.get_executor();
   }
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
 
   /// Cancel any asynchronous operations that are waiting on the resolver.
   /**
@@ -195,11 +186,12 @@ public:
    */
   void cancel()
   {
-    return this->get_service().cancel(this->get_implementation());
+    return impl_.get_service().cancel(impl_.get_implementation());
   }
 
 #if !defined(BOOST_ASIO_NO_DEPRECATED)
-  /// (Deprecated.) Perform forward resolution of a query to a list of entries.
+  /// (Deprecated: Use overload with separate host and service parameters.)
+  /// Perform forward resolution of a query to a list of entries.
   /**
    * This function is used to resolve a query into a list of endpoint entries.
    *
@@ -214,13 +206,14 @@ public:
   results_type resolve(const query& q)
   {
     boost::system::error_code ec;
-    results_type r = this->get_service().resolve(
-        this->get_implementation(), q, ec);
+    results_type r = impl_.get_service().resolve(
+        impl_.get_implementation(), q, ec);
     boost::asio::detail::throw_error(ec, "resolve");
     return r;
   }
 
-  /// (Deprecated.) Perform forward resolution of a query to a list of entries.
+  /// (Deprecated: Use overload with separate host and service parameters.)
+  /// Perform forward resolution of a query to a list of entries.
   /**
    * This function is used to resolve a query into a list of endpoint entries.
    *
@@ -234,7 +227,7 @@ public:
    */
   results_type resolve(const query& q, boost::system::error_code& ec)
   {
-    return this->get_service().resolve(this->get_implementation(), q, ec);
+    return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
   }
 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
 
@@ -334,7 +327,8 @@ public:
    *
    * @param resolve_flags A set of flags that determine how name resolution
    * should be performed. The default flags are suitable for communication with
-   * remote hosts.
+   * remote hosts. See the @ref resolver_base documentation for the set of
+   * available flags.
    *
    * @returns A range object representing the list of endpoint entries. A
    * successful call to this function is guaranteed to return a non-empty
@@ -359,8 +353,8 @@ public:
     boost::system::error_code ec;
     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
         static_cast<std::string>(service), resolve_flags);
-    results_type r = this->get_service().resolve(
-        this->get_implementation(), q, ec);
+    results_type r = impl_.get_service().resolve(
+        impl_.get_implementation(), q, ec);
     boost::asio::detail::throw_error(ec, "resolve");
     return r;
   }
@@ -383,7 +377,8 @@ public:
    *
    * @param resolve_flags A set of flags that determine how name resolution
    * should be performed. The default flags are suitable for communication with
-   * remote hosts.
+   * remote hosts. See the @ref resolver_base documentation for the set of
+   * available flags.
    *
    * @param ec Set to indicate what error occurred, if any.
    *
@@ -408,7 +403,7 @@ public:
   {
     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
         static_cast<std::string>(service), resolve_flags);
-    return this->get_service().resolve(this->get_implementation(), q, ec);
+    return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
   }
 
   /// Perform forward resolution of a query to a list of entries.
@@ -517,7 +512,8 @@ public:
    *
    * @param resolve_flags A set of flags that determine how name resolution
    * should be performed. The default flags are suitable for communication with
-   * remote hosts.
+   * remote hosts. See the @ref resolver_base documentation for the set of
+   * available flags.
    *
    * @returns A range object representing the list of endpoint entries. A
    * successful call to this function is guaranteed to return a non-empty
@@ -544,8 +540,8 @@ public:
     basic_resolver_query<protocol_type> q(
         protocol, static_cast<std::string>(host),
         static_cast<std::string>(service), resolve_flags);
-    results_type r = this->get_service().resolve(
-        this->get_implementation(), q, ec);
+    results_type r = impl_.get_service().resolve(
+        impl_.get_implementation(), q, ec);
     boost::asio::detail::throw_error(ec, "resolve");
     return r;
   }
@@ -571,7 +567,8 @@ public:
    *
    * @param resolve_flags A set of flags that determine how name resolution
    * should be performed. The default flags are suitable for communication with
-   * remote hosts.
+   * remote hosts. See the @ref resolver_base documentation for the set of
+   * available flags.
    *
    * @param ec Set to indicate what error occurred, if any.
    *
@@ -597,12 +594,12 @@ public:
     basic_resolver_query<protocol_type> q(
         protocol, static_cast<std::string>(host),
         static_cast<std::string>(service), resolve_flags);
-    return this->get_service().resolve(this->get_implementation(), q, ec);
+    return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
   }
 
 #if !defined(BOOST_ASIO_NO_DEPRECATED)
-  /// (Deprecated.) Asynchronously perform forward resolution of a query to a
-  /// list of entries.
+  /// (Deprecated: Use overload with separate host and service parameters.)
+  /// Asynchronously perform forward resolution of a query to a list of entries.
   /**
    * This function is used to asynchronously resolve a query into a list of
    * endpoint entries.
@@ -617,36 +614,26 @@ public:
    *   resolver::results_type results // Resolved endpoints as a range.
    * ); @endcode
    * Regardless of whether the asynchronous operation completes immediately or
-   * not, the handler will not be invoked from within this function. Invocation
-   * of the handler will be performed in a manner equivalent to using
-   * boost::asio::io_context::post().
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using boost::asio::post().
    *
    * A successful resolve operation is guaranteed to pass a non-empty range to
    * the handler.
    */
-  template <typename ResolveHandler>
-  BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+  template <
+      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+        results_type)) ResolveHandler
+          BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
       void (boost::system::error_code, results_type))
   async_resolve(const query& q,
-      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
+      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
+        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
   {
-    // If you get an error on the following line it means that your handler does
-    // not meet the documented type requirements for a ResolveHandler.
-    BOOST_ASIO_RESOLVE_HANDLER_CHECK(
-        ResolveHandler, handler, results_type) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    return this->get_service().async_resolve(this->get_implementation(), q,
-        BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    boost::asio::async_completion<ResolveHandler,
-      void (boost::system::error_code, results_type)> init(handler);
-
-    this->get_service().async_resolve(
-        this->get_implementation(), q, init.completion_handler);
-
-    return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return boost::asio::async_initiate<ResolveHandler,
+      void (boost::system::error_code, results_type)>(
+        initiate_async_resolve(this), handler, q);
   }
 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
 
@@ -674,9 +661,9 @@ public:
    *   resolver::results_type results // Resolved endpoints as a range.
    * ); @endcode
    * Regardless of whether the asynchronous operation completes immediately or
-   * not, the handler will not be invoked from within this function. Invocation
-   * of the handler will be performed in a manner equivalent to using
-   * boost::asio::io_context::post().
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using boost::asio::post().
    *
    * A successful resolve operation is guaranteed to pass a non-empty range to
    * the handler.
@@ -692,12 +679,16 @@ public:
    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
    * may use additional locations when resolving service names.
    */
-  template <typename ResolveHandler>
-  BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+  template <
+      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+        results_type)) ResolveHandler
+          BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
       void (boost::system::error_code, results_type))
   async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
       BOOST_ASIO_STRING_VIEW_PARAM service,
-      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
+      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
+        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
   {
     return async_resolve(host, service, resolver_base::flags(),
         BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
@@ -721,7 +712,8 @@ public:
    *
    * @param resolve_flags A set of flags that determine how name resolution
    * should be performed. The default flags are suitable for communication with
-   * remote hosts.
+   * remote hosts. See the @ref resolver_base documentation for the set of
+   * available flags.
    *
    * @param handler The handler to be called when the resolve operation
    * completes. Copies will be made of the handler as required. The function
@@ -731,9 +723,9 @@ public:
    *   resolver::results_type results // Resolved endpoints as a range.
    * ); @endcode
    * Regardless of whether the asynchronous operation completes immediately or
-   * not, the handler will not be invoked from within this function. Invocation
-   * of the handler will be performed in a manner equivalent to using
-   * boost::asio::io_context::post().
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using boost::asio::post().
    *
    * A successful resolve operation is guaranteed to pass a non-empty range to
    * the handler.
@@ -749,34 +741,24 @@ public:
    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
    * may use additional locations when resolving service names.
    */
-  template <typename ResolveHandler>
-  BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+  template <
+      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+        results_type)) ResolveHandler
+          BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
       void (boost::system::error_code, results_type))
   async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
       BOOST_ASIO_STRING_VIEW_PARAM service,
       resolver_base::flags resolve_flags,
-      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
+      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
+        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
   {
-    // If you get an error on the following line it means that your handler does
-    // not meet the documented type requirements for a ResolveHandler.
-    BOOST_ASIO_RESOLVE_HANDLER_CHECK(
-        ResolveHandler, handler, results_type) type_check;
-
     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
         static_cast<std::string>(service), resolve_flags);
 
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    return this->get_service().async_resolve(this->get_implementation(), q,
-        BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    boost::asio::async_completion<ResolveHandler,
-      void (boost::system::error_code, results_type)> init(handler);
-
-    this->get_service().async_resolve(
-        this->get_implementation(), q, init.completion_handler);
-
-    return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return boost::asio::async_initiate<ResolveHandler,
+      void (boost::system::error_code, results_type)>(
+        initiate_async_resolve(this), handler, q);
   }
 
   /// Asynchronously perform forward resolution of a query to a list of entries.
@@ -806,9 +788,9 @@ public:
    *   resolver::results_type results // Resolved endpoints as a range.
    * ); @endcode
    * Regardless of whether the asynchronous operation completes immediately or
-   * not, the handler will not be invoked from within this function. Invocation
-   * of the handler will be performed in a manner equivalent to using
-   * boost::asio::io_context::post().
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using boost::asio::post().
    *
    * A successful resolve operation is guaranteed to pass a non-empty range to
    * the handler.
@@ -824,12 +806,16 @@ public:
    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
    * may use additional locations when resolving service names.
    */
-  template <typename ResolveHandler>
-  BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+  template <
+      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+        results_type)) ResolveHandler
+          BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
       void (boost::system::error_code, results_type))
   async_resolve(const protocol_type& protocol,
       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
-      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
+      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
+        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
   {
     return async_resolve(protocol, host, service, resolver_base::flags(),
         BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
@@ -856,7 +842,8 @@ public:
    *
    * @param resolve_flags A set of flags that determine how name resolution
    * should be performed. The default flags are suitable for communication with
-   * remote hosts.
+   * remote hosts. See the @ref resolver_base documentation for the set of
+   * available flags.
    *
    * @param handler The handler to be called when the resolve operation
    * completes. Copies will be made of the handler as required. The function
@@ -866,9 +853,9 @@ public:
    *   resolver::results_type results // Resolved endpoints as a range.
    * ); @endcode
    * Regardless of whether the asynchronous operation completes immediately or
-   * not, the handler will not be invoked from within this function. Invocation
-   * of the handler will be performed in a manner equivalent to using
-   * boost::asio::io_context::post().
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using boost::asio::post().
    *
    * A successful resolve operation is guaranteed to pass a non-empty range to
    * the handler.
@@ -884,35 +871,25 @@ public:
    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
    * may use additional locations when resolving service names.
    */
-  template <typename ResolveHandler>
-  BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+  template <
+      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+        results_type)) ResolveHandler
+          BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
       void (boost::system::error_code, results_type))
   async_resolve(const protocol_type& protocol,
       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
       resolver_base::flags resolve_flags,
-      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
+      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
+        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
   {
-    // If you get an error on the following line it means that your handler does
-    // not meet the documented type requirements for a ResolveHandler.
-    BOOST_ASIO_RESOLVE_HANDLER_CHECK(
-        ResolveHandler, handler, results_type) type_check;
-
     basic_resolver_query<protocol_type> q(
         protocol, static_cast<std::string>(host),
         static_cast<std::string>(service), resolve_flags);
 
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    return this->get_service().async_resolve(this->get_implementation(), q,
-        BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    boost::asio::async_completion<ResolveHandler,
-      void (boost::system::error_code, results_type)> init(handler);
-
-    this->get_service().async_resolve(
-        this->get_implementation(), q, init.completion_handler);
-
-    return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return boost::asio::async_initiate<ResolveHandler,
+      void (boost::system::error_code, results_type)>(
+        initiate_async_resolve(this), handler, q);
   }
 
   /// Perform reverse resolution of an endpoint to a list of entries.
@@ -932,8 +909,8 @@ public:
   results_type resolve(const endpoint_type& e)
   {
     boost::system::error_code ec;
-    results_type i = this->get_service().resolve(
-        this->get_implementation(), e, ec);
+    results_type i = impl_.get_service().resolve(
+        impl_.get_implementation(), e, ec);
     boost::asio::detail::throw_error(ec, "resolve");
     return i;
   }
@@ -954,7 +931,7 @@ public:
    */
   results_type resolve(const endpoint_type& e, boost::system::error_code& ec)
   {
-    return this->get_service().resolve(this->get_implementation(), e, ec);
+    return impl_.get_service().resolve(impl_.get_implementation(), e, ec);
   }
 
   /// Asynchronously perform reverse resolution of an endpoint to a list of
@@ -974,37 +951,76 @@ public:
    *   resolver::results_type results // Resolved endpoints as a range.
    * ); @endcode
    * Regardless of whether the asynchronous operation completes immediately or
-   * not, the handler will not be invoked from within this function. Invocation
-   * of the handler will be performed in a manner equivalent to using
-   * boost::asio::io_context::post().
+   * not, the handler will not be invoked from within this function. On
+   * immediate completion, invocation of the handler will be performed in a
+   * manner equivalent to using boost::asio::post().
    *
    * A successful resolve operation is guaranteed to pass a non-empty range to
    * the handler.
    */
-  template <typename ResolveHandler>
-  BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
+  template <
+      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+        results_type)) ResolveHandler
+          BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
+  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
       void (boost::system::error_code, results_type))
   async_resolve(const endpoint_type& e,
-      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
+      BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
+        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
   {
-    // If you get an error on the following line it means that your handler does
-    // not meet the documented type requirements for a ResolveHandler.
-    BOOST_ASIO_RESOLVE_HANDLER_CHECK(
-        ResolveHandler, handler, results_type) type_check;
+    return boost::asio::async_initiate<ResolveHandler,
+      void (boost::system::error_code, results_type)>(
+        initiate_async_resolve(this), handler, e);
+  }
 
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    return this->get_service().async_resolve(this->get_implementation(), e,
-        BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-    boost::asio::async_completion<ResolveHandler,
-      void (boost::system::error_code, results_type)> init(handler);
+private:
+  // Disallow copying and assignment.
+  basic_resolver(const basic_resolver&) BOOST_ASIO_DELETED;
+  basic_resolver& operator=(const basic_resolver&) BOOST_ASIO_DELETED;
 
-    this->get_service().async_resolve(
-        this->get_implementation(), e, init.completion_handler);
+  class initiate_async_resolve
+  {
+  public:
+    typedef Executor executor_type;
 
-    return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-  }
+    explicit initiate_async_resolve(basic_resolver* self)
+      : self_(self)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return self_->get_executor();
+    }
+
+    template <typename ResolveHandler, typename Query>
+    void operator()(BOOST_ASIO_MOVE_ARG(ResolveHandler) handler,
+        const Query& q) const
+    {
+      // If you get an error on the following line it means that your handler
+      // does not meet the documented type requirements for a ResolveHandler.
+      BOOST_ASIO_RESOLVE_HANDLER_CHECK(
+          ResolveHandler, handler, results_type) type_check;
+
+      boost::asio::detail::non_const_lvalue<ResolveHandler> handler2(handler);
+      self_->impl_.get_service().async_resolve(
+          self_->impl_.get_implementation(), q, handler2.value,
+          self_->impl_.get_implementation_executor());
+    }
+
+  private:
+    basic_resolver* self_;
+  };
+
+# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  boost::asio::detail::io_object_impl<
+    boost::asio::detail::winrt_resolver_service<InternetProtocol>,
+    Executor> impl_;
+# else
+  boost::asio::detail::io_object_impl<
+    boost::asio::detail::resolver_service<InternetProtocol>,
+    Executor> impl_;
+# endif
 };
 
 } // namespace ip
@@ -1013,8 +1029,4 @@ public:
 
 #include <boost/asio/detail/pop_options.hpp>
 
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
 #endif // BOOST_ASIO_IP_BASIC_RESOLVER_HPP