Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / asio / impl / read_until.hpp
index 63b86f8..17e1506 100644 (file)
@@ -952,12 +952,25 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_delim_v1
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_delim_v1
   {
-    template <typename ReadHandler, typename AsyncReadStream,
-        typename DynamicBuffer_v1>
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_delim_v1(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v1>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
         char delim) const
     {
       // If you get an error on the following line it means that your handler
@@ -968,9 +981,12 @@ namespace detail
       read_until_delim_op_v1<AsyncReadStream,
         typename decay<DynamicBuffer_v1>::type,
           typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
             delim, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -1014,9 +1030,10 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream,
-    typename DynamicBuffer_v1, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@@ -1028,8 +1045,8 @@ async_read_until(AsyncReadStream& s,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_delim_v1(), handler,
-      &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim);
+      detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim);
 }
 
 namespace detail
@@ -1219,12 +1236,25 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_delim_string_v1
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_delim_string_v1
   {
-    template <typename ReadHandler, typename AsyncReadStream,
-        typename DynamicBuffer_v1>
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_delim_string_v1(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v1>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
         const std::string& delim) const
     {
       // If you get an error on the following line it means that your handler
@@ -1235,9 +1265,12 @@ namespace detail
       read_until_delim_string_op_v1<AsyncReadStream,
         typename decay<DynamicBuffer_v1>::type,
           typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
             delim, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -1281,9 +1314,10 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream,
-    typename DynamicBuffer_v1, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@@ -1296,8 +1330,8 @@ async_read_until(AsyncReadStream& s,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_delim_string_v1(),
-      handler, &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+      detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
       static_cast<std::string>(delim));
 }
 
@@ -1494,13 +1528,25 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_expr_v1
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_expr_v1
   {
-    template <typename ReadHandler, typename AsyncReadStream,
-        typename DynamicBuffer_v1, typename RegEx>
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_expr_v1(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v1, typename RegEx>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
-        const RegEx& expr) const
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const RegEx& expr) const
     {
       // If you get an error on the following line it means that your handler
       // does not meet the documented type requirements for a ReadHandler.
@@ -1510,9 +1556,12 @@ namespace detail
       read_until_expr_op_v1<AsyncReadStream,
         typename decay<DynamicBuffer_v1>::type,
           RegEx, typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
             expr, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -1556,9 +1605,10 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream,
-    typename DynamicBuffer_v1, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@@ -1571,8 +1621,8 @@ async_read_until(AsyncReadStream& s,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_expr_v1(), handler,
-      &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr);
+      detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr);
 }
 
 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
@@ -1765,12 +1815,26 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_match_v1
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_match_v1
   {
-    template <typename ReadHandler, typename AsyncReadStream,
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_match_v1(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler,
         typename DynamicBuffer_v1, typename MatchCondition>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
         MatchCondition match_condition) const
     {
       // If you get an error on the following line it means that your handler
@@ -1781,9 +1845,12 @@ namespace detail
       read_until_match_op_v1<AsyncReadStream,
         typename decay<DynamicBuffer_v1>::type,
           MatchCondition, typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
             match_condition, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -1827,9 +1894,11 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream, typename DynamicBuffer_v1,
-    typename MatchCondition, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream,
+    typename DynamicBuffer_v1, typename MatchCondition,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
@@ -1842,14 +1911,16 @@ async_read_until(AsyncReadStream& s,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_match_v1(), handler,
-      &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition);
+      detail::initiate_async_read_until_match_v1<AsyncReadStream>(s), handler,
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition);
 }
 
 #if !defined(BOOST_ASIO_NO_IOSTREAM)
 
-template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename Allocator,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     boost::asio::basic_streambuf<Allocator>& b,
@@ -1859,8 +1930,10 @@ async_read_until(AsyncReadStream& s,
       delim, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
 }
 
-template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename Allocator,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     boost::asio::basic_streambuf<Allocator>& b,
@@ -1873,8 +1946,10 @@ async_read_until(AsyncReadStream& s,
 
 #if defined(BOOST_ASIO_HAS_BOOST_REGEX)
 
-template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename Allocator,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
@@ -1886,9 +1961,10 @@ async_read_until(AsyncReadStream& s,
 
 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
 
-template <typename AsyncReadStream, typename Allocator,
-    typename MatchCondition, typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename Allocator, typename MatchCondition,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     boost::asio::basic_streambuf<Allocator>& b,
@@ -2087,13 +2163,25 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_delim_v2
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_delim_v2
   {
-    template <typename ReadHandler, typename AsyncReadStream,
-        typename DynamicBuffer_v2>
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_delim_v2(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v2>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
-        char delim) const
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, char delim) const
     {
       // If you get an error on the following line it means that your handler
       // does not meet the documented type requirements for a ReadHandler.
@@ -2103,9 +2191,12 @@ namespace detail
       read_until_delim_op_v2<AsyncReadStream,
         typename decay<DynamicBuffer_v2>::type,
           typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
             delim, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -2149,9 +2240,10 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream,
-    typename DynamicBuffer_v2, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
     char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@@ -2161,8 +2253,8 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_delim_v2(), handler,
-      &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim);
+      detail::initiate_async_read_until_delim_v2<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim);
 }
 
 namespace detail
@@ -2360,12 +2452,25 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_delim_string_v2
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_delim_string_v2
   {
-    template <typename ReadHandler, typename AsyncReadStream,
-        typename DynamicBuffer_v2>
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_delim_string_v2(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v2>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
         const std::string& delim) const
     {
       // If you get an error on the following line it means that your handler
@@ -2376,9 +2481,12 @@ namespace detail
       read_until_delim_string_op_v2<AsyncReadStream,
         typename decay<DynamicBuffer_v2>::type,
           typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
             delim, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -2423,8 +2531,10 @@ struct associated_executor<
 #endif // !defined(GENERATING_DOCUMENTATION)
 
 template <typename AsyncReadStream,
-    typename DynamicBuffer_v2, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+    typename DynamicBuffer_v2,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s,
     DynamicBuffer_v2 buffers, BOOST_ASIO_STRING_VIEW_PARAM delim,
@@ -2435,8 +2545,8 @@ async_read_until(AsyncReadStream& s,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_delim_string_v2(),
-      handler, &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+      detail::initiate_async_read_until_delim_string_v2<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
       static_cast<std::string>(delim));
 }
 
@@ -2641,12 +2751,25 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_expr_v2
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_expr_v2
   {
-    template <typename ReadHandler, typename AsyncReadStream,
-        typename DynamicBuffer_v2, typename RegEx>
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_expr_v2(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v2, typename RegEx>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
         const RegEx& expr) const
     {
       // If you get an error on the following line it means that your handler
@@ -2657,9 +2780,12 @@ namespace detail
       read_until_expr_op_v2<AsyncReadStream,
         typename decay<DynamicBuffer_v2>::type,
           RegEx, typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
             expr, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -2703,9 +2829,10 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream,
-    typename DynamicBuffer_v2, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
     const boost::regex& expr, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@@ -2715,8 +2842,8 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_expr_v2(), handler,
-      &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr);
+      detail::initiate_async_read_until_expr_v2<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr);
 }
 
 #endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
@@ -2917,12 +3044,26 @@ namespace detail
         function, this_handler->handler_);
   }
 
-  struct initiate_async_read_until_match_v2
+  template <typename AsyncReadStream>
+  class initiate_async_read_until_match_v2
   {
-    template <typename ReadHandler, typename AsyncReadStream,
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_until_match_v2(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler,
         typename DynamicBuffer_v2, typename MatchCondition>
     void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
-        AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
         MatchCondition match_condition) const
     {
       // If you get an error on the following line it means that your handler
@@ -2933,9 +3074,12 @@ namespace detail
       read_until_match_op_v2<AsyncReadStream,
         typename decay<DynamicBuffer_v2>::type,
           MatchCondition, typename decay<ReadHandler>::type>(
-            *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+            stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
             match_condition, handler2.value)(boost::system::error_code(), 0, 1);
     }
+
+  private:
+    AsyncReadStream& stream_;
   };
 } // namespace detail
 
@@ -2979,9 +3123,11 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream, typename DynamicBuffer_v2,
-    typename MatchCondition, typename ReadHandler>
-BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream,
+    typename DynamicBuffer_v2, typename MatchCondition,
+    BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
+      std::size_t)) ReadHandler>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
     MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@@ -2992,8 +3138,8 @@ async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
 {
   return async_initiate<ReadHandler,
     void (boost::system::error_code, std::size_t)>(
-      detail::initiate_async_read_until_match_v2(), handler,
-      &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition);
+      detail::initiate_async_read_until_match_v2<AsyncReadStream>(s), handler,
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition);
 }
 
 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)