]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/asio/impl/read.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / asio / impl / read.hpp
index 9fbddc964e9f23c82e4970154f46ff8b46614e91..2bcbe15bb3f98fe48fb1086e72dea5571c5a15c8 100644 (file)
@@ -2,7 +2,7 @@
 // impl/read.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)
@@ -29,6 +29,7 @@
 #include <boost/asio/detail/handler_cont_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
 #include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
 #include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 
@@ -69,7 +70,8 @@ std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
     >::type*)
 {
   return detail::read_buffer_sequence(s, buffers,
-      boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
+      boost::asio::buffer_sequence_begin(buffers),
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
 }
 
 template <typename SyncReadStream, typename MutableBufferSequence>
@@ -103,22 +105,26 @@ inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
     >::type*)
 {
   boost::system::error_code ec;
-  std::size_t bytes_transferred = read(s, buffers, completion_condition, ec);
+  std::size_t bytes_transferred = read(s, buffers,
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
   boost::asio::detail::throw_error(ec, "read");
   return bytes_transferred;
 }
 
-template <typename SyncReadStream, typename DynamicBuffer,
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncReadStream, typename DynamicBuffer_v1,
     typename CompletionCondition>
 std::size_t read(SyncReadStream& s,
-    BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+    BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
     CompletionCondition completion_condition, boost::system::error_code& ec,
     typename enable_if<
-      is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+        && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
     >::type*)
 {
-  typename decay<DynamicBuffer>::type b(
-      BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
+  typename decay<DynamicBuffer_v1>::type b(
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
 
   ec = boost::system::error_code();
   std::size_t total_transferred = 0;
@@ -141,45 +147,48 @@ std::size_t read(SyncReadStream& s,
   return total_transferred;
 }
 
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
 inline std::size_t read(SyncReadStream& s,
-    BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+    BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
     typename enable_if<
-      is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+        && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
     >::type*)
 {
   boost::system::error_code ec;
   std::size_t bytes_transferred = read(s,
-      BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers), transfer_all(), ec);
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec);
   boost::asio::detail::throw_error(ec, "read");
   return bytes_transferred;
 }
 
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
 inline std::size_t read(SyncReadStream& s,
-    BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+    BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
     boost::system::error_code& ec,
     typename enable_if<
-      is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+        && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
     >::type*)
 {
-  return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+  return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
       transfer_all(), ec);
 }
 
-template <typename SyncReadStream, typename DynamicBuffer,
+template <typename SyncReadStream, typename DynamicBuffer_v1,
     typename CompletionCondition>
 inline std::size_t read(SyncReadStream& s,
-    BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+    BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
     CompletionCondition completion_condition,
     typename enable_if<
-      is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+        && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
     >::type*)
 {
   boost::system::error_code ec;
   std::size_t bytes_transferred = read(s,
-      BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
-      completion_condition, ec);
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
   boost::asio::detail::throw_error(ec, "read");
   return bytes_transferred;
 }
@@ -193,7 +202,8 @@ inline std::size_t read(SyncReadStream& s,
     boost::asio::basic_streambuf<Allocator>& b,
     CompletionCondition completion_condition, boost::system::error_code& ec)
 {
-  return read(s, basic_streambuf_ref<Allocator>(b), completion_condition, ec);
+  return read(s, basic_streambuf_ref<Allocator>(b),
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
 }
 
 template <typename SyncReadStream, typename Allocator>
@@ -217,11 +227,87 @@ inline std::size_t read(SyncReadStream& s,
     boost::asio::basic_streambuf<Allocator>& b,
     CompletionCondition completion_condition)
 {
-  return read(s, basic_streambuf_ref<Allocator>(b), completion_condition);
+  return read(s, basic_streambuf_ref<Allocator>(b),
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
 }
 
 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncReadStream, typename DynamicBuffer_v2,
+    typename CompletionCondition>
+std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+    CompletionCondition completion_condition, boost::system::error_code& ec,
+    typename enable_if<
+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+    >::type*)
+{
+  DynamicBuffer_v2& b = buffers;
+
+  ec = boost::system::error_code();
+  std::size_t total_transferred = 0;
+  std::size_t max_size = detail::adapt_completion_condition_result(
+        completion_condition(ec, total_transferred));
+  std::size_t bytes_available = std::min<std::size_t>(
+        std::max<std::size_t>(512, b.capacity() - b.size()),
+        std::min<std::size_t>(max_size, b.max_size() - b.size()));
+  while (bytes_available > 0)
+  {
+    std::size_t pos = b.size();
+    b.grow(bytes_available);
+    std::size_t bytes_transferred = s.read_some(
+        b.data(pos, bytes_available), ec);
+    b.shrink(bytes_available - bytes_transferred);
+    total_transferred += bytes_transferred;
+    max_size = detail::adapt_completion_condition_result(
+          completion_condition(ec, total_transferred));
+    bytes_available = std::min<std::size_t>(
+          std::max<std::size_t>(512, b.capacity() - b.size()),
+          std::min<std::size_t>(max_size, b.max_size() - b.size()));
+  }
+  return total_transferred;
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+    typename enable_if<
+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+    >::type*)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = read(s,
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec);
+  boost::asio::detail::throw_error(ec, "read");
+  return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+    boost::system::error_code& ec,
+    typename enable_if<
+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+    >::type*)
+{
+  return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+      transfer_all(), ec);
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2,
+    typename CompletionCondition>
+inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+    CompletionCondition completion_condition,
+    typename enable_if<
+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+    >::type*)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = read(s,
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
+  boost::asio::detail::throw_error(ec, "read");
+  return bytes_transferred;
+}
 
 namespace detail
 {
@@ -233,7 +319,7 @@ namespace detail
   {
   public:
     read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
-        CompletionCondition completion_condition, ReadHandler& handler)
+        CompletionCondition& completion_condition, ReadHandler& handler)
       : detail::base_from_completion_cond<
           CompletionCondition>(completion_condition),
         stream_(stream),
@@ -254,9 +340,11 @@ namespace detail
     }
 
     read_op(read_op&& other)
-      : detail::base_from_completion_cond<CompletionCondition>(other),
+      : detail::base_from_completion_cond<CompletionCondition>(
+          BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+            CompletionCondition>)(other)),
         stream_(other.stream_),
-        buffers_(other.buffers_),
+        buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
         start_(other.start_),
         handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
     {
@@ -287,9 +375,11 @@ namespace detail
     }
 
   //private:
+    typedef boost::asio::detail::consuming_buffers<mutable_buffer,
+        MutableBufferSequence, MutableBufferIterator> buffers_type;
+
     AsyncReadStream& stream_;
-    boost::asio::detail::consuming_buffers<mutable_buffer,
-        MutableBufferSequence, MutableBufferIterator> buffers_;
+    buffers_type buffers_;
     int start_;
     ReadHandler handler_;
   };
@@ -355,13 +445,50 @@ namespace detail
       typename ReadHandler>
   inline void start_read_buffer_sequence_op(AsyncReadStream& stream,
       const MutableBufferSequence& buffers, const MutableBufferIterator&,
-      CompletionCondition completion_condition, ReadHandler& handler)
+      CompletionCondition& completion_condition, ReadHandler& handler)
   {
     detail::read_op<AsyncReadStream, MutableBufferSequence,
       MutableBufferIterator, CompletionCondition, ReadHandler>(
         stream, buffers, completion_condition, handler)(
           boost::system::error_code(), 0, 1);
   }
+
+  template <typename AsyncReadStream>
+  class initiate_async_read_buffer_sequence
+  {
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_buffer_sequence(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename MutableBufferSequence,
+        typename CompletionCondition>
+    void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+        const MutableBufferSequence& buffers,
+        BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) 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.
+      BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+      non_const_lvalue<ReadHandler> handler2(handler);
+      non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+      start_read_buffer_sequence_op(stream_, buffers,
+          boost::asio::buffer_sequence_begin(buffers),
+          completion_cond2.value, handler2.value);
+    }
+
+  private:
+    AsyncReadStream& stream_;
+  };
 } // namespace detail
 
 #if !defined(GENERATING_DOCUMENTATION)
@@ -406,9 +533,11 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream, typename MutableBufferSequence,
-    typename CompletionCondition, typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream,
+    typename MutableBufferSequence, typename CompletionCondition,
+    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(AsyncReadStream& s, const MutableBufferSequence& buffers,
     CompletionCondition completion_condition,
@@ -417,23 +546,16 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
       is_mutable_buffer_sequence<MutableBufferSequence>::value
     >::type*)
 {
-  // If you get an error on the following line it means that your handler does
-  // not meet the documented type requirements for a ReadHandler.
-  BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-  async_completion<ReadHandler,
-    void (boost::system::error_code, std::size_t)> init(handler);
-
-  detail::start_read_buffer_sequence_op(s, buffers,
-      boost::asio::buffer_sequence_begin(buffers), completion_condition,
-      init.completion_handler);
-
-  return init.result.get();
+  return async_initiate<ReadHandler,
+    void (boost::system::error_code, std::size_t)>(
+      detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s), handler,
+      buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
 }
 
 template <typename AsyncReadStream, typename MutableBufferSequence,
-    typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+    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(AsyncReadStream& s, const MutableBufferSequence& buffers,
     BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
@@ -441,32 +563,26 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
       is_mutable_buffer_sequence<MutableBufferSequence>::value
     >::type*)
 {
-  // If you get an error on the following line it means that your handler does
-  // not meet the documented type requirements for a ReadHandler.
-  BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-  async_completion<ReadHandler,
-    void (boost::system::error_code, std::size_t)> init(handler);
-
-  detail::start_read_buffer_sequence_op(s, buffers,
-      boost::asio::buffer_sequence_begin(buffers), transfer_all(),
-      init.completion_handler);
-
-  return init.result.get();
+  return async_initiate<ReadHandler,
+    void (boost::system::error_code, std::size_t)>(
+      detail::initiate_async_read_buffer_sequence<AsyncReadStream>(s),
+      handler, buffers, transfer_all());
 }
 
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
 namespace detail
 {
-  template <typename AsyncReadStream, typename DynamicBuffer,
+  template <typename AsyncReadStream, typename DynamicBuffer_v1,
       typename CompletionCondition, typename ReadHandler>
-  class read_dynbuf_op
+  class read_dynbuf_v1_op
     : detail::base_from_completion_cond<CompletionCondition>
   {
   public:
     template <typename BufferSequence>
-    read_dynbuf_op(AsyncReadStream& stream,
+    read_dynbuf_v1_op(AsyncReadStream& stream,
         BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
-        CompletionCondition completion_condition, ReadHandler& handler)
+        CompletionCondition& completion_condition, ReadHandler& handler)
       : detail::base_from_completion_cond<
           CompletionCondition>(completion_condition),
         stream_(stream),
@@ -478,7 +594,7 @@ namespace detail
     }
 
 #if defined(BOOST_ASIO_HAS_MOVE)
-    read_dynbuf_op(const read_dynbuf_op& other)
+    read_dynbuf_v1_op(const read_dynbuf_v1_op& other)
       : detail::base_from_completion_cond<CompletionCondition>(other),
         stream_(other.stream_),
         buffers_(other.buffers_),
@@ -488,10 +604,12 @@ namespace detail
     {
     }
 
-    read_dynbuf_op(read_dynbuf_op&& other)
-      : detail::base_from_completion_cond<CompletionCondition>(other),
+    read_dynbuf_v1_op(read_dynbuf_v1_op&& other)
+      : detail::base_from_completion_cond<CompletionCondition>(
+          BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+            CompletionCondition>)(other)),
         stream_(other.stream_),
-        buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
+        buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
         start_(other.start_),
         total_transferred_(other.total_transferred_),
         handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
@@ -515,7 +633,7 @@ namespace detail
         for (;;)
         {
           stream_.async_read_some(buffers_.prepare(bytes_available),
-              BOOST_ASIO_MOVE_CAST(read_dynbuf_op)(*this));
+              BOOST_ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this));
           return; default:
           total_transferred_ += bytes_transferred;
           buffers_.commit(bytes_transferred);
@@ -535,36 +653,36 @@ namespace detail
 
   //private:
     AsyncReadStream& stream_;
-    DynamicBuffer buffers_;
+    DynamicBuffer_v1 buffers_;
     int start_;
     std::size_t total_transferred_;
     ReadHandler handler_;
   };
 
-  template <typename AsyncReadStream, typename DynamicBuffer,
+  template <typename AsyncReadStream, typename DynamicBuffer_v1,
       typename CompletionCondition, typename ReadHandler>
   inline void* asio_handler_allocate(std::size_t size,
-      read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
         CompletionCondition, ReadHandler>* this_handler)
   {
     return boost_asio_handler_alloc_helpers::allocate(
         size, this_handler->handler_);
   }
 
-  template <typename AsyncReadStream, typename DynamicBuffer,
+  template <typename AsyncReadStream, typename DynamicBuffer_v1,
       typename CompletionCondition, typename ReadHandler>
   inline void asio_handler_deallocate(void* pointer, std::size_t size,
-      read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
         CompletionCondition, ReadHandler>* this_handler)
   {
     boost_asio_handler_alloc_helpers::deallocate(
         pointer, size, this_handler->handler_);
   }
 
-  template <typename AsyncReadStream, typename DynamicBuffer,
+  template <typename AsyncReadStream, typename DynamicBuffer_v1,
       typename CompletionCondition, typename ReadHandler>
   inline bool asio_handler_is_continuation(
-      read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
         CompletionCondition, ReadHandler>* this_handler)
   {
     return this_handler->start_ == 0 ? true
@@ -573,10 +691,10 @@ namespace detail
   }
 
   template <typename Function, typename AsyncReadStream,
-      typename DynamicBuffer, typename CompletionCondition,
+      typename DynamicBuffer_v1, typename CompletionCondition,
       typename ReadHandler>
   inline void asio_handler_invoke(Function& function,
-      read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
         CompletionCondition, ReadHandler>* this_handler)
   {
     boost_asio_handler_invoke_helpers::invoke(
@@ -584,49 +702,88 @@ namespace detail
   }
 
   template <typename Function, typename AsyncReadStream,
-      typename DynamicBuffer, typename CompletionCondition,
+      typename DynamicBuffer_v1, typename CompletionCondition,
       typename ReadHandler>
   inline void asio_handler_invoke(const Function& function,
-      read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
         CompletionCondition, ReadHandler>* this_handler)
   {
     boost_asio_handler_invoke_helpers::invoke(
         function, this_handler->handler_);
   }
+
+  template <typename AsyncReadStream>
+  class initiate_async_read_dynbuf_v1
+  {
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_dynbuf_v1(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v1,
+        typename CompletionCondition>
+    void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+        BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) 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.
+      BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+      non_const_lvalue<ReadHandler> handler2(handler);
+      non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+      read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,
+        CompletionCondition, typename decay<ReadHandler>::type>(
+          stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+            completion_cond2.value, handler2.value)(
+              boost::system::error_code(), 0, 1);
+    }
+
+  private:
+    AsyncReadStream& stream_;
+  };
 } // namespace detail
 
 #if !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
     typename CompletionCondition, typename ReadHandler, typename Allocator>
 struct associated_allocator<
-    detail::read_dynbuf_op<AsyncReadStream,
-      DynamicBuffer, CompletionCondition, ReadHandler>,
+    detail::read_dynbuf_v1_op<AsyncReadStream,
+      DynamicBuffer_v1, CompletionCondition, ReadHandler>,
     Allocator>
 {
   typedef typename associated_allocator<ReadHandler, Allocator>::type type;
 
   static type get(
-      const detail::read_dynbuf_op<AsyncReadStream,
-        DynamicBuffer, CompletionCondition, ReadHandler>& h,
+      const detail::read_dynbuf_v1_op<AsyncReadStream,
+        DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
       const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
   {
     return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
   }
 };
 
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
     typename CompletionCondition, typename ReadHandler, typename Executor>
 struct associated_executor<
-    detail::read_dynbuf_op<AsyncReadStream,
-      DynamicBuffer, CompletionCondition, ReadHandler>,
+    detail::read_dynbuf_v1_op<AsyncReadStream,
+      DynamicBuffer_v1, CompletionCondition, ReadHandler>,
     Executor>
 {
   typedef typename associated_executor<ReadHandler, Executor>::type type;
 
   static type get(
-      const detail::read_dynbuf_op<AsyncReadStream,
-        DynamicBuffer, CompletionCondition, ReadHandler>& h,
+      const detail::read_dynbuf_v1_op<AsyncReadStream,
+        DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
       const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
   {
     return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
@@ -635,57 +792,57 @@ struct associated_executor<
 
 #endif // !defined(GENERATING_DOCUMENTATION)
 
-template <typename AsyncReadStream,
-    typename DynamicBuffer, typename ReadHandler>
-inline 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>
+inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
     void (boost::system::error_code, std::size_t))
 async_read(AsyncReadStream& s,
-    BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+    BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
     BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
     typename enable_if<
-      is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+        && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
     >::type*)
 {
   return async_read(s,
-      BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
       transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
 }
 
-template <typename AsyncReadStream, typename DynamicBuffer,
-    typename CompletionCondition, typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream,
+    typename DynamicBuffer_v1, typename CompletionCondition,
+    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(AsyncReadStream& s,
-    BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+    BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
     CompletionCondition completion_condition,
     BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
     typename enable_if<
-      is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+        && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
     >::type*)
 {
   // If you get an error on the following line it means that your handler does
   // not meet the documented type requirements for a ReadHandler.
   BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
 
-  async_completion<ReadHandler,
-    void (boost::system::error_code, std::size_t)> init(handler);
-
-  detail::read_dynbuf_op<AsyncReadStream,
-    typename decay<DynamicBuffer>::type,
-      CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
-        ReadHandler, void (boost::system::error_code, std::size_t))>(
-          s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
-            completion_condition, init.completion_handler)(
-              boost::system::error_code(), 0, 1);
-
-  return init.result.get();
+  return async_initiate<ReadHandler,
+    void (boost::system::error_code, std::size_t)>(
+      detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
 }
 
 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
 #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(AsyncReadStream& s, basic_streambuf<Allocator>& b,
     BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
@@ -694,20 +851,291 @@ async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
       BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
 }
 
-template <typename AsyncReadStream, typename Allocator,
-    typename CompletionCondition, typename ReadHandler>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+template <typename AsyncReadStream,
+    typename Allocator, typename CompletionCondition,
+    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(AsyncReadStream& s, basic_streambuf<Allocator>& b,
     CompletionCondition completion_condition,
     BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
 {
   return async_read(s, basic_streambuf_ref<Allocator>(b),
-      completion_condition, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
+      BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
 }
 
 #endif // !defined(BOOST_ASIO_NO_IOSTREAM)
 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+namespace detail
+{
+  template <typename AsyncReadStream, typename DynamicBuffer_v2,
+      typename CompletionCondition, typename ReadHandler>
+  class read_dynbuf_v2_op
+    : detail::base_from_completion_cond<CompletionCondition>
+  {
+  public:
+    template <typename BufferSequence>
+    read_dynbuf_v2_op(AsyncReadStream& stream,
+        BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
+        CompletionCondition& completion_condition, ReadHandler& handler)
+      : detail::base_from_completion_cond<
+          CompletionCondition>(completion_condition),
+        stream_(stream),
+        buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
+        start_(0),
+        total_transferred_(0),
+        bytes_available_(0),
+        handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
+    {
+    }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+    read_dynbuf_v2_op(const read_dynbuf_v2_op& other)
+      : detail::base_from_completion_cond<CompletionCondition>(other),
+        stream_(other.stream_),
+        buffers_(other.buffers_),
+        start_(other.start_),
+        total_transferred_(other.total_transferred_),
+        bytes_available_(other.bytes_available_),
+        handler_(other.handler_)
+    {
+    }
+
+    read_dynbuf_v2_op(read_dynbuf_v2_op&& other)
+      : detail::base_from_completion_cond<CompletionCondition>(
+          BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+            CompletionCondition>)(other)),
+        stream_(other.stream_),
+        buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
+        start_(other.start_),
+        total_transferred_(other.total_transferred_),
+        bytes_available_(other.bytes_available_),
+        handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
+    {
+    }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred, int start = 0)
+    {
+      std::size_t max_size, pos;
+      switch (start_ = start)
+      {
+        case 1:
+        max_size = this->check_for_completion(ec, total_transferred_);
+        bytes_available_ = std::min<std::size_t>(
+              std::max<std::size_t>(512,
+                buffers_.capacity() - buffers_.size()),
+              std::min<std::size_t>(max_size,
+                buffers_.max_size() - buffers_.size()));
+        for (;;)
+        {
+          pos = buffers_.size();
+          buffers_.grow(bytes_available_);
+          stream_.async_read_some(buffers_.data(pos, bytes_available_),
+              BOOST_ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this));
+          return; default:
+          total_transferred_ += bytes_transferred;
+          buffers_.shrink(bytes_available_ - bytes_transferred);
+          max_size = this->check_for_completion(ec, total_transferred_);
+          bytes_available_ = std::min<std::size_t>(
+                std::max<std::size_t>(512,
+                  buffers_.capacity() - buffers_.size()),
+                std::min<std::size_t>(max_size,
+                  buffers_.max_size() - buffers_.size()));
+          if ((!ec && bytes_transferred == 0) || bytes_available_ == 0)
+            break;
+        }
+
+        handler_(ec, static_cast<const std::size_t&>(total_transferred_));
+      }
+    }
+
+  //private:
+    AsyncReadStream& stream_;
+    DynamicBuffer_v2 buffers_;
+    int start_;
+    std::size_t total_transferred_;
+    std::size_t bytes_available_;
+    ReadHandler handler_;
+  };
+
+  template <typename AsyncReadStream, typename DynamicBuffer_v2,
+      typename CompletionCondition, typename ReadHandler>
+  inline void* asio_handler_allocate(std::size_t size,
+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    return boost_asio_handler_alloc_helpers::allocate(
+        size, this_handler->handler_);
+  }
+
+  template <typename AsyncReadStream, typename DynamicBuffer_v2,
+      typename CompletionCondition, typename ReadHandler>
+  inline void asio_handler_deallocate(void* pointer, std::size_t size,
+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    boost_asio_handler_alloc_helpers::deallocate(
+        pointer, size, this_handler->handler_);
+  }
+
+  template <typename AsyncReadStream, typename DynamicBuffer_v2,
+      typename CompletionCondition, typename ReadHandler>
+  inline bool asio_handler_is_continuation(
+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    return this_handler->start_ == 0 ? true
+      : boost_asio_handler_cont_helpers::is_continuation(
+          this_handler->handler_);
+  }
+
+  template <typename Function, typename AsyncReadStream,
+      typename DynamicBuffer_v2, typename CompletionCondition,
+      typename ReadHandler>
+  inline void asio_handler_invoke(Function& function,
+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, this_handler->handler_);
+  }
+
+  template <typename Function, typename AsyncReadStream,
+      typename DynamicBuffer_v2, typename CompletionCondition,
+      typename ReadHandler>
+  inline void asio_handler_invoke(const Function& function,
+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, this_handler->handler_);
+  }
+
+  template <typename AsyncReadStream>
+  class initiate_async_read_dynbuf_v2
+  {
+  public:
+    typedef typename AsyncReadStream::executor_type executor_type;
+
+    explicit initiate_async_read_dynbuf_v2(AsyncReadStream& stream)
+      : stream_(stream)
+    {
+    }
+
+    executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+    {
+      return stream_.get_executor();
+    }
+
+    template <typename ReadHandler, typename DynamicBuffer_v2,
+        typename CompletionCondition>
+    void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+        BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+        BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) 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.
+      BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+      non_const_lvalue<ReadHandler> handler2(handler);
+      non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+      read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,
+        CompletionCondition, typename decay<ReadHandler>::type>(
+          stream_, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+            completion_cond2.value, handler2.value)(
+              boost::system::error_code(), 0, 1);
+    }
+
+  private:
+    AsyncReadStream& stream_;
+  };
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+    typename CompletionCondition, typename ReadHandler, typename Allocator>
+struct associated_allocator<
+    detail::read_dynbuf_v2_op<AsyncReadStream,
+      DynamicBuffer_v2, CompletionCondition, ReadHandler>,
+    Allocator>
+{
+  typedef typename associated_allocator<ReadHandler, Allocator>::type type;
+
+  static type get(
+      const detail::read_dynbuf_v2_op<AsyncReadStream,
+        DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
+      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
+  }
+};
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+    typename CompletionCondition, typename ReadHandler, typename Executor>
+struct associated_executor<
+    detail::read_dynbuf_v2_op<AsyncReadStream,
+      DynamicBuffer_v2, CompletionCondition, ReadHandler>,
+    Executor>
+{
+  typedef typename associated_executor<ReadHandler, Executor>::type type;
+
+  static type get(
+      const detail::read_dynbuf_v2_op<AsyncReadStream,
+        DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
+      const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
+  }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+    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(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+    BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+    typename enable_if<
+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+    >::type*)
+{
+  return async_read(s,
+      BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+      transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+}
+
+template <typename AsyncReadStream,
+    typename DynamicBuffer_v2, typename CompletionCondition,
+    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(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+    CompletionCondition completion_condition,
+    BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+    typename enable_if<
+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+    >::type*)
+{
+  // If you get an error on the following line it means that your handler does
+  // not meet the documented type requirements for a ReadHandler.
+  BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+  return async_initiate<ReadHandler,
+    void (boost::system::error_code, std::size_t)>(
+      detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),
+      handler, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+      BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
+}
 
 } // namespace asio
 } // namespace boost