Minimise overloads of buffer_size() and buffer_copy().

The public interface is now specified in terms of buffer sequences. The
optimised overloads for const_buffer, mutable_buffer, etc. are now
implementation details.
diff --git a/asio/include/asio/buffer.hpp b/asio/include/asio/buffer.hpp
index d7e5cc8..e9ae6ba 100644
--- a/asio/include/asio/buffer.hpp
+++ b/asio/include/asio/buffer.hpp
@@ -515,52 +515,43 @@
 
 /*@}*/
 
-/** @defgroup buffer_size asio::buffer_size
- *
- * @brief The asio::buffer_size function determines the total number of
- * bytes in a buffer or buffer sequence.
- */
-/*@{*/
-
-/// Get the number of bytes in a modifiable buffer.
-inline std::size_t buffer_size(const mutable_buffer& b) ASIO_NOEXCEPT
-{
-  return b.size();
-}
-
-/// Get the number of bytes in a non-modifiable buffer.
-inline std::size_t buffer_size(const const_buffer& b) ASIO_NOEXCEPT
-{
-  return b.size();
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Get the number of bytes in a modifiable buffer.
-inline std::size_t buffer_size(const mutable_buffers_1& b) ASIO_NOEXCEPT
-{
-  return b.size();
-}
-
-
-/// Get the number of bytes in a non-modifiable buffer.
-inline std::size_t buffer_size(const const_buffers_1& b) ASIO_NOEXCEPT
-{
-  return b.size();
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
 namespace detail {
 
+// Tag types used to select appropriately optimised overloads.
+struct one_buffer {};
+struct multiple_buffers {};
+
+// Helper trait to detect single buffers.
+template <typename BufferSequence>
+struct buffer_sequence_cardinality :
+  conditional<
+    is_same<BufferSequence, mutable_buffer>::value
+#if !defined(ASIO_NO_DEPRECATED)
+      || is_same<BufferSequence, mutable_buffers_1>::value
+      || is_same<BufferSequence, const_buffers_1>::value
+#endif // !defined(ASIO_NO_DEPRECATED)
+      || is_same<BufferSequence, const_buffer>::value,
+    one_buffer, multiple_buffers>::type {};
+
 template <typename Iterator>
-inline std::size_t buffer_size(Iterator begin, Iterator end)
+inline std::size_t buffer_size(one_buffer,
+    Iterator begin, Iterator) ASIO_NOEXCEPT
+{
+  return const_buffer(*begin).size();
+}
+
+template <typename Iterator>
+inline std::size_t buffer_size(multiple_buffers,
+    Iterator begin, Iterator end) ASIO_NOEXCEPT
 {
   std::size_t total_buffer_size = 0;
 
   Iterator iter = begin;
   for (; iter != end; ++iter)
-    total_buffer_size += iter->size();
+  {
+    const_buffer b(*iter);
+    total_buffer_size += b.size();
+  }
 
   return total_buffer_size;
 }
@@ -568,23 +559,32 @@
 } // namespace detail
 
 /// Get the total number of bytes in a buffer sequence.
-/** 
+/**
+ * The @c buffer_size function determines the total size of all buffers in the
+ * buffer sequence, as if computed as follows:
+ *
+ * @code size_t total_size = 0;
+ * auto i = asio::buffer_sequence_begin(buffers);
+ * auto end = asio::buffer_sequence_end(buffers);
+ * for (; i != end; ++i)
+ * {
+ *   const_buffer b(*i);
+ *   total_size += b.size();
+ * }
+ * return total_size; @endcode
+ *
  * The @c BufferSequence template parameter may meet either of the @c
  * ConstBufferSequence or @c MutableBufferSequence type requirements.
  */
 template <typename BufferSequence>
-inline std::size_t buffer_size(const BufferSequence& b,
-    typename enable_if<
-      is_const_buffer_sequence<BufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
+inline std::size_t buffer_size(const BufferSequence& b) ASIO_NOEXCEPT
 {
   return detail::buffer_size(
+      detail::buffer_sequence_cardinality<BufferSequence>(),
       asio::buffer_sequence_begin(b),
       asio::buffer_sequence_end(b));
 }
 
-/*@}*/
-
 #if !defined(ASIO_NO_DEPRECATED)
 
 /** @defgroup buffer_cast asio::buffer_cast
@@ -787,9 +787,10 @@
  *
  * The @ref buffer_copy function may be used to copy raw bytes between
  * individual buffers and buffer sequences.
- *
- * In particular, when used with the @ref buffer_size, the @ref buffer_copy
- * function can be used to linearise a sequence of buffers. For example:
+*
+ * In particular, when used with the @ref buffer_size function, the @ref
+ * buffer_copy function can be used to linearise a sequence of buffers. For
+ * example:
  *
  * @code vector<const_buffer> buffers = ...;
  *
@@ -1862,27 +1863,10 @@
  */
 /*@{*/
 
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const const_buffer& source) ASIO_NOEXCEPT
+namespace detail {
+
+inline std::size_t buffer_copy_1(const mutable_buffer& target,
+    const const_buffer& source)
 {
   using namespace std; // For memcpy.
   std::size_t target_size = target.size();
@@ -1892,438 +1876,72 @@
   return n;
 }
 
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const const_buffers_1& source) ASIO_NOEXCEPT
+template <typename TargetIterator, typename SourceIterator>
+inline std::size_t buffer_copy(one_buffer, one_buffer,
+    TargetIterator target_begin, TargetIterator,
+    SourceIterator source_begin, SourceIterator) ASIO_NOEXCEPT
 {
-  return buffer_copy(target, static_cast<const const_buffer&>(source));
+  return (buffer_copy_1)(*target_begin, *source_begin);
 }
 
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const mutable_buffer& source) ASIO_NOEXCEPT
+template <typename TargetIterator, typename SourceIterator>
+inline std::size_t buffer_copy(one_buffer, one_buffer,
+    TargetIterator target_begin, TargetIterator,
+    SourceIterator source_begin, SourceIterator,
+    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
 {
-  return buffer_copy(target, const_buffer(source));
+  return (buffer_copy_1)(*target_begin,
+      asio::buffer(*source_begin, max_bytes_to_copy));
 }
 
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const mutable_buffers_1& source) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, const_buffer(source));
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-namespace detail {
-
-template <typename SourceIterator>
-std::size_t buffer_copy_from_sequence(const mutable_buffer& target,
-    SourceIterator source_begin, SourceIterator source_end) ASIO_NOEXCEPT
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(one_buffer, multiple_buffers,
+    TargetIterator target_begin, TargetIterator,
+    SourceIterator source_begin, SourceIterator source_end,
+    std::size_t max_bytes_to_copy
+      = (std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT
 {
   std::size_t total_bytes_copied = 0;
   SourceIterator source_iter = source_begin;
 
-  for (mutable_buffer target_buffer(target);
+  for (mutable_buffer target_buffer(
+        asio::buffer(*target_begin, max_bytes_to_copy));
       target_buffer.size() && source_iter != source_end; ++source_iter)
   {
     const_buffer source_buffer(*source_iter);
-    std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
     total_bytes_copied += bytes_copied;
-    target_buffer = target_buffer + bytes_copied;
+    target_buffer += bytes_copied;
   }
 
   return total_bytes_copied;
 }
 
-} // namespace detail
-
-/// Copies bytes from a source buffer sequence to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename ConstBufferSequence>
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const ConstBufferSequence& source,
-    typename enable_if<
-      is_const_buffer_sequence<ConstBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return detail::buffer_copy_from_sequence(target,
-      asio::buffer_sequence_begin(source),
-      asio::buffer_sequence_end(source));
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const const_buffer& source) ASIO_NOEXCEPT
-{
-  return buffer_copy(static_cast<const mutable_buffer&>(target), source);
-}
-
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const const_buffers_1& source) ASIO_NOEXCEPT
-{
-  return buffer_copy(static_cast<const mutable_buffer&>(target),
-      static_cast<const const_buffer&>(source));
-}
-
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const mutable_buffer& source) ASIO_NOEXCEPT
-{
-  return buffer_copy(static_cast<const mutable_buffer&>(target),
-      const_buffer(source));
-}
-
-/// Copies bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const mutable_buffers_1& source) ASIO_NOEXCEPT
-{
-  return buffer_copy(static_cast<const mutable_buffer&>(target),
-      const_buffer(source));
-}
-
-/// Copies bytes from a source buffer sequence to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename ConstBufferSequence>
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const ConstBufferSequence& source,
-    typename enable_if<
-      is_const_buffer_sequence<ConstBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(static_cast<const mutable_buffer&>(target), source);
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-namespace detail {
-
-template <typename TargetIterator>
-std::size_t buffer_copy_to_sequence(TargetIterator target_begin,
-    TargetIterator target_end, const const_buffer& source) ASIO_NOEXCEPT
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, one_buffer,
+    TargetIterator target_begin, TargetIterator target_end,
+    SourceIterator source_begin, SourceIterator,
+    std::size_t max_bytes_to_copy
+      = (std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT
 {
   std::size_t total_bytes_copied = 0;
   TargetIterator target_iter = target_begin;
 
-  for (const_buffer source_buffer(source);
+  for (const_buffer source_buffer(
+        asio::buffer(*source_begin, max_bytes_to_copy));
       source_buffer.size() && target_iter != target_end; ++target_iter)
   {
     mutable_buffer target_buffer(*target_iter);
-    std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
     total_bytes_copied += bytes_copied;
-    source_buffer = source_buffer + bytes_copied;
+    source_buffer += bytes_copied;
   }
 
   return total_bytes_copied;
 }
 
-} // namespace detail
-
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const const_buffer& source,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return detail::buffer_copy_to_sequence(
-      asio::buffer_sequence_begin(target),
-      asio::buffer_sequence_end(target), source);
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const const_buffers_1& source,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, static_cast<const const_buffer&>(source));
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const mutable_buffer& source,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, const_buffer(source));
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies bytes from a source buffer to a target buffer sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const mutable_buffers_1& source,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, const_buffer(source));
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-namespace detail {
-
 template <typename TargetIterator, typename SourceIterator>
-std::size_t buffer_copy_to_sequence_from_sequence(
+std::size_t buffer_copy(multiple_buffers, multiple_buffers,
     TargetIterator target_begin, TargetIterator target_end,
     SourceIterator source_begin, SourceIterator source_end) ASIO_NOEXCEPT
 {
@@ -2343,7 +1961,55 @@
     const_buffer source_buffer =
       const_buffer(*source_iter) + source_buffer_offset;
 
-    std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
+    total_bytes_copied += bytes_copied;
+
+    if (bytes_copied == target_buffer.size())
+    {
+      ++target_iter;
+      target_buffer_offset = 0;
+    }
+    else
+      target_buffer_offset += bytes_copied;
+
+    if (bytes_copied == source_buffer.size())
+    {
+      ++source_iter;
+      source_buffer_offset = 0;
+    }
+    else
+      source_buffer_offset += bytes_copied;
+  }
+
+  return total_bytes_copied;
+}
+
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, multiple_buffers,
+    TargetIterator target_begin, TargetIterator target_end,
+    SourceIterator source_begin, SourceIterator source_end,
+    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
+{
+  std::size_t total_bytes_copied = 0;
+
+  TargetIterator target_iter = target_begin;
+  std::size_t target_buffer_offset = 0;
+
+  SourceIterator source_iter = source_begin;
+  std::size_t source_buffer_offset = 0;
+
+  while (total_bytes_copied != max_bytes_to_copy
+      && target_iter != target_end && source_iter != source_end)
+  {
+    mutable_buffer target_buffer =
+      mutable_buffer(*target_iter) + target_buffer_offset;
+
+    const_buffer source_buffer =
+      const_buffer(*source_iter) + source_buffer_offset;
+
+    std::size_t bytes_copied = (buffer_copy_1)(
+        target_buffer, asio::buffer(source_buffer,
+          max_bytes_to_copy - total_bytes_copied));
     total_bytes_copied += bytes_copied;
 
     if (bytes_copied == target_buffer.size())
@@ -2389,540 +2055,17 @@
  */
 template <typename MutableBufferSequence, typename ConstBufferSequence>
 inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const ConstBufferSequence& source,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value &&
-      is_const_buffer_sequence<ConstBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
+    const ConstBufferSequence& source) ASIO_NOEXCEPT
 {
-  return detail::buffer_copy_to_sequence_from_sequence(
+  return detail::buffer_copy(
+      detail::buffer_sequence_cardinality<MutableBufferSequence>(),
+      detail::buffer_sequence_cardinality<ConstBufferSequence>(),
       asio::buffer_sequence_begin(target),
       asio::buffer_sequence_end(target),
       asio::buffer_sequence_begin(source),
       asio::buffer_sequence_end(source));
 }
 
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const const_buffer& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const const_buffers_1& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const mutable_buffer& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const mutable_buffers_1& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer sequence to a target
-/// buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename ConstBufferSequence>
-inline std::size_t buffer_copy(const mutable_buffer& target,
-    const ConstBufferSequence& source, std::size_t max_bytes_to_copy,
-    typename enable_if<
-      is_const_buffer_sequence<ConstBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const const_buffer& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const const_buffers_1& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const mutable_buffer& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-/// Copies a limited number of bytes from a source buffer to a target buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const mutable_buffers_1& source,
-    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-/// Copies a limited number of bytes from a source buffer sequence to a target
-/// buffer.
-/**
- * @param target A modifiable buffer representing the memory region to which
- * the bytes will be copied.
- *
- * @param source A non-modifiable buffer sequence representing the memory
- * regions from which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename ConstBufferSequence>
-inline std::size_t buffer_copy(const mutable_buffers_1& target,
-    const ConstBufferSequence& source, std::size_t max_bytes_to_copy,
-    typename enable_if<
-      is_const_buffer_sequence<ConstBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(buffer(target, max_bytes_to_copy), source);
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const const_buffer& source, std::size_t max_bytes_to_copy,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, buffer(source, max_bytes_to_copy));
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A non-modifiable buffer representing the memory region from
- * which the bytes will be copied.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const const_buffers_1& source, std::size_t max_bytes_to_copy,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, buffer(source, max_bytes_to_copy));
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const mutable_buffer& source, std::size_t max_bytes_to_copy,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, buffer(source, max_bytes_to_copy));
-}
-
-#if !defined(ASIO_NO_DEPRECATED)
-
-/// Copies a limited number of bytes from a source buffer to a target buffer
-/// sequence.
-/**
- * @param target A modifiable buffer sequence representing the memory regions to
- * which the bytes will be copied.
- *
- * @param source A modifiable buffer representing the memory region from which
- * the bytes will be copied. The contents of the source buffer will not be
- * modified.
- *
- * @param max_bytes_to_copy The maximum number of bytes to be copied.
- *
- * @returns The number of bytes copied.
- *
- * @note The number of bytes copied is the lesser of:
- *
- * @li @c buffer_size(target)
- *
- * @li @c buffer_size(source)
- *
- * @li @c max_bytes_to_copy
- *
- * This function is implemented in terms of @c memcpy, and consequently it
- * cannot be used to copy between overlapping memory regions.
- */
-template <typename MutableBufferSequence>
-inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const mutable_buffers_1& source, std::size_t max_bytes_to_copy,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
-{
-  return buffer_copy(target, buffer(source, max_bytes_to_copy));
-}
-
-#endif // !defined(ASIO_NO_DEPRECATED)
-
-namespace detail {
-
-template <typename TargetIterator, typename SourceIterator>
-std::size_t buffer_copy_n_to_sequence_from_sequence(
-    TargetIterator target_begin, TargetIterator target_end,
-    SourceIterator source_begin, SourceIterator source_end,
-    std::size_t max_bytes_to_copy)
-{
-  std::size_t total_bytes_copied = 0;
-
-  TargetIterator target_iter = target_begin;
-  std::size_t target_buffer_offset = 0;
-
-  SourceIterator source_iter = source_begin;
-  std::size_t source_buffer_offset = 0;
-
-  while (total_bytes_copied != max_bytes_to_copy
-      && target_iter != target_end && source_iter != source_end)
-  {
-    mutable_buffer target_buffer =
-      mutable_buffer(*target_iter) + target_buffer_offset;
-
-    const_buffer source_buffer =
-      const_buffer(*source_iter) + source_buffer_offset;
-
-    std::size_t bytes_copied = buffer_copy(target_buffer,
-        source_buffer, max_bytes_to_copy - total_bytes_copied);
-    total_bytes_copied += bytes_copied;
-
-    if (bytes_copied == target_buffer.size())
-    {
-      ++target_iter;
-      target_buffer_offset = 0;
-    }
-    else
-      target_buffer_offset += bytes_copied;
-
-    if (bytes_copied == source_buffer.size())
-    {
-      ++source_iter;
-      source_buffer_offset = 0;
-    }
-    else
-      source_buffer_offset += bytes_copied;
-  }
-
-  return total_bytes_copied;
-}
-
-} // namespace detail
-
 /// Copies a limited number of bytes from a source buffer sequence to a target
 /// buffer sequence.
 /**
@@ -2949,13 +2092,12 @@
  */
 template <typename MutableBufferSequence, typename ConstBufferSequence>
 inline std::size_t buffer_copy(const MutableBufferSequence& target,
-    const ConstBufferSequence& source, std::size_t max_bytes_to_copy,
-    typename enable_if<
-      is_mutable_buffer_sequence<MutableBufferSequence>::value &&
-      is_const_buffer_sequence<ConstBufferSequence>::value
-    >::type* = 0) ASIO_NOEXCEPT
+    const ConstBufferSequence& source,
+    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT
 {
-  return detail::buffer_copy_n_to_sequence_from_sequence(
+  return detail::buffer_copy(
+      detail::buffer_sequence_cardinality<MutableBufferSequence>(),
+      detail::buffer_sequence_cardinality<ConstBufferSequence>(),
       asio::buffer_sequence_begin(target),
       asio::buffer_sequence_end(target),
       asio::buffer_sequence_begin(source),
diff --git a/asio/src/doc/reference.qbk b/asio/src/doc/reference.qbk
index f2cd644..b29e338 100644
--- a/asio/src/doc/reference.qbk
+++ b/asio/src/doc/reference.qbk
@@ -42552,7 +42552,7 @@
 
 The [link asio.reference.buffer_copy `buffer_copy`]  function may be used to copy raw bytes between individual buffers and buffer sequences.
 
-In particular, when used with the [link asio.reference.buffer_size `buffer_size`] , the [link asio.reference.buffer_copy `buffer_copy`]  function can be used to linearise a sequence of buffers. For example:
+In particular, when used with the [link asio.reference.buffer_size `buffer_size`]  function, the [link asio.reference.buffer_copy `buffer_copy`]  function can be used to linearise a sequence of buffers. For example:
 
 
 
@@ -43718,215 +43718,23 @@
 The `asio::buffer_copy` function is used to copy bytes from a source buffer (or buffer sequence) to a target buffer (or buffer sequence). 
 
       
+  template<
+      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
   std::size_t ``[link asio.reference.buffer_copy.overload1 buffer_copy]``(
-      const mutable_buffer & target,
-      const const_buffer & source);
+      const MutableBufferSequence & target,
+      const ConstBufferSequence & source);
   ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload1 more...]]``
 
+  template<
+      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
+      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
   std::size_t ``[link asio.reference.buffer_copy.overload2 buffer_copy]``(
-      const mutable_buffer & target,
-      const const_buffers_1 & source);
+      const MutableBufferSequence & target,
+      const ConstBufferSequence & source,
+      std::size_t max_bytes_to_copy);
   ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload2 more...]]``
 
-  std::size_t ``[link asio.reference.buffer_copy.overload3 buffer_copy]``(
-      const mutable_buffer & target,
-      const mutable_buffer & source);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload3 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload4 buffer_copy]``(
-      const mutable_buffer & target,
-      const mutable_buffers_1 & source);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload4 more...]]``
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload5 buffer_copy]``(
-      const mutable_buffer & target,
-      const ConstBufferSequence & source,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload5 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload6 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const const_buffer & source);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload6 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload7 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const const_buffers_1 & source);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload7 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload8 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const mutable_buffer & source);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload8 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload9 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const mutable_buffers_1 & source);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload9 more...]]``
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload10 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const ConstBufferSequence & source,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload10 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload11 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const const_buffer & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload11 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload12 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const const_buffers_1 & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload12 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload13 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const mutable_buffer & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload13 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload14 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const mutable_buffers_1 & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload14 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload15 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const ConstBufferSequence & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value &&is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload15 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload16 buffer_copy]``(
-      const mutable_buffer & target,
-      const const_buffer & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload16 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload17 buffer_copy]``(
-      const mutable_buffer & target,
-      const const_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload17 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload18 buffer_copy]``(
-      const mutable_buffer & target,
-      const mutable_buffer & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload18 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload19 buffer_copy]``(
-      const mutable_buffer & target,
-      const mutable_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload19 more...]]``
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload20 buffer_copy]``(
-      const mutable_buffer & target,
-      const ConstBufferSequence & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload20 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload21 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const const_buffer & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload21 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload22 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const const_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload22 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload23 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const mutable_buffer & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload23 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_copy.overload24 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const mutable_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload24 more...]]``
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload25 buffer_copy]``(
-      const mutable_buffers_1 & target,
-      const ConstBufferSequence & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload25 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload26 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const const_buffer & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload26 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload27 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const const_buffers_1 & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload27 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload28 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const mutable_buffer & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload28 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload29 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const mutable_buffers_1 & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload29 more...]]``
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``,
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t ``[link asio.reference.buffer_copy.overload30 buffer_copy]``(
-      const MutableBufferSequence & target,
-      const ConstBufferSequence & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value &&is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_copy.overload30 more...]]``
-
 The `buffer_copy` function is available in two forms:
 
 
@@ -43957,669 +43765,7 @@
 ['Convenience header: ][^asio.hpp]
 
 
-[section:overload1 buffer_copy (1 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const const_buffer & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload2 buffer_copy (2 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const const_buffers_1 & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload3 buffer_copy (3 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const mutable_buffer & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload4 buffer_copy (4 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const mutable_buffers_1 & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload5 buffer_copy (5 of 30 overloads)]
-
-
-Copies bytes from a source buffer sequence to a target buffer. 
-
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const ConstBufferSequence & source,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer sequence representing the memory regions from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload6 buffer_copy (6 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const const_buffer & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload7 buffer_copy (7 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const const_buffers_1 & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload8 buffer_copy (8 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const mutable_buffer & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload9 buffer_copy (9 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const mutable_buffers_1 & source);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload10 buffer_copy (10 of 30 overloads)]
-
-
-Copies bytes from a source buffer sequence to a target buffer. 
-
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const ConstBufferSequence & source,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer sequence representing the memory regions from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload11 buffer_copy (11 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const const_buffer & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload12 buffer_copy (12 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const const_buffers_1 & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload13 buffer_copy (13 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const mutable_buffer & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload14 buffer_copy (14 of 30 overloads)]
-
-
-Copies bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const mutable_buffers_1 & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload15 buffer_copy (15 of 30 overloads)]
+[section:overload1 buffer_copy (1 of 2 overloads)]
 
 
 Copies bytes from a source buffer sequence to a target buffer sequence. 
@@ -44630,8 +43776,7 @@
       typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
   std::size_t buffer_copy(
       const MutableBufferSequence & target,
-      const ConstBufferSequence & source,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value &&is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
+      const ConstBufferSequence & source);
 
 
 
@@ -44669,753 +43814,7 @@
 
 
 
-[section:overload16 buffer_copy (16 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const const_buffer & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload17 buffer_copy (17 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const const_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload18 buffer_copy (18 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const mutable_buffer & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload19 buffer_copy (19 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const mutable_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload20 buffer_copy (20 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer sequence to a target buffer. 
-
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t buffer_copy(
-      const mutable_buffer & target,
-      const ConstBufferSequence & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer sequence representing the memory regions from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload21 buffer_copy (21 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const const_buffer & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload22 buffer_copy (22 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const const_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload23 buffer_copy (23 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const mutable_buffer & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload24 buffer_copy (24 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer. 
-
-
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const mutable_buffers_1 & source,
-      std::size_t max_bytes_to_copy);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload25 buffer_copy (25 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer sequence to a target buffer. 
-
-
-  template<
-      typename ``[link asio.reference.ConstBufferSequence ConstBufferSequence]``>
-  std::size_t buffer_copy(
-      const mutable_buffers_1 & target,
-      const ConstBufferSequence & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer representing the memory region to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer sequence representing the memory regions from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload26 buffer_copy (26 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const const_buffer & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload27 buffer_copy (27 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const const_buffers_1 & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A non-modifiable buffer representing the memory region from which the bytes will be copied.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload28 buffer_copy (28 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const mutable_buffer & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload29 buffer_copy (29 of 30 overloads)]
-
-
-Copies a limited number of bytes from a source buffer to a target buffer sequence. 
-
-
-  template<
-      typename ``[link asio.reference.MutableBufferSequence MutableBufferSequence]``>
-  std::size_t buffer_copy(
-      const MutableBufferSequence & target,
-      const mutable_buffers_1 & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value >::type *  = 0);
-
-
-
-[heading Parameters]
-    
-
-[variablelist
-  
-[[target][A modifiable buffer sequence representing the memory regions to which the bytes will be copied.]]
-
-[[source][A modifiable buffer representing the memory region from which the bytes will be copied. The contents of the source buffer will not be modified.]]
-
-[[max_bytes_to_copy][The maximum number of bytes to be copied.]]
-
-]
-
-
-[heading Return Value]
-      
-The number of bytes copied.
-
-
-[heading Remarks]
-      
-The number of bytes copied is the lesser of:
-
-
-* `buffer_size(target)` 
-
-
-* `buffer_size(source)` 
-
-
-* `max_bytes_to_copy` 
-
-This function is implemented in terms of `memcpy`, and consequently it cannot be used to copy between overlapping memory regions. 
-
-
-[endsect]
-
-
-
-[section:overload30 buffer_copy (30 of 30 overloads)]
+[section:overload2 buffer_copy (2 of 2 overloads)]
 
 
 Copies a limited number of bytes from a source buffer sequence to a target buffer sequence. 
@@ -45427,8 +43826,7 @@
   std::size_t buffer_copy(
       const MutableBufferSequence & target,
       const ConstBufferSequence & source,
-      std::size_t max_bytes_to_copy,
-      typename enable_if< is_mutable_buffer_sequence< MutableBufferSequence >::value &&is_const_buffer_sequence< ConstBufferSequence >::value >::type *  = 0);
+      std::size_t max_bytes_to_copy);
 
 
 
@@ -45668,34 +44066,37 @@
 
 [endsect]
 
+
 [section:buffer_size buffer_size]
 
 [indexterm1 asio.indexterm.buffer_size..buffer_size] 
-The `asio::buffer_size` function determines the total number of bytes in a buffer or buffer sequence. 
+Get the total number of bytes in a buffer sequence. 
 
-      
-  std::size_t ``[link asio.reference.buffer_size.overload1 buffer_size]``(
-      const mutable_buffer & b);
-  ``  [''''&raquo;''' [link asio.reference.buffer_size.overload1 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_size.overload2 buffer_size]``(
-      const const_buffer & b);
-  ``  [''''&raquo;''' [link asio.reference.buffer_size.overload2 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_size.overload3 buffer_size]``(
-      const mutable_buffers_1 & b);
-  ``  [''''&raquo;''' [link asio.reference.buffer_size.overload3 more...]]``
-
-  std::size_t ``[link asio.reference.buffer_size.overload4 buffer_size]``(
-      const const_buffers_1 & b);
-  ``  [''''&raquo;''' [link asio.reference.buffer_size.overload4 more...]]``
 
   template<
       typename BufferSequence>
-  std::size_t ``[link asio.reference.buffer_size.overload5 buffer_size]``(
-      const BufferSequence & b,
-      typename enable_if< is_const_buffer_sequence< BufferSequence >::value >::type *  = 0);
-  ``  [''''&raquo;''' [link asio.reference.buffer_size.overload5 more...]]``
+  std::size_t buffer_size(
+      const BufferSequence & b);
+
+
+The `buffer_size` function determines the total size of all buffers in the buffer sequence, as if computed as follows:
+
+
+
+   size_t total_size = 0;
+   auto i = asio::buffer_sequence_begin(buffers);
+   auto end = asio::buffer_sequence_end(buffers);
+   for (; i != end; ++i)
+   {
+     const_buffer b(*i);
+     total_size += b.size();
+   }
+   return total_size; 
+
+
+
+
+The `BufferSequence` template parameter may meet either of the `ConstBufferSequence` or `MutableBufferSequence` type requirements. 
 
 [heading Requirements]
 
@@ -45704,87 +44105,9 @@
 ['Convenience header: ][^asio.hpp]
 
 
-[section:overload1 buffer_size (1 of 5 overloads)]
-
-
-Get the number of bytes in a modifiable buffer. 
-
-
-  std::size_t buffer_size(
-      const mutable_buffer & b);
-
-
-
 [endsect]
 
 
-
-[section:overload2 buffer_size (2 of 5 overloads)]
-
-
-Get the number of bytes in a non-modifiable buffer. 
-
-
-  std::size_t buffer_size(
-      const const_buffer & b);
-
-
-
-[endsect]
-
-
-
-[section:overload3 buffer_size (3 of 5 overloads)]
-
-
-Get the number of bytes in a modifiable buffer. 
-
-
-  std::size_t buffer_size(
-      const mutable_buffers_1 & b);
-
-
-
-[endsect]
-
-
-
-[section:overload4 buffer_size (4 of 5 overloads)]
-
-
-Get the number of bytes in a non-modifiable buffer. 
-
-
-  std::size_t buffer_size(
-      const const_buffers_1 & b);
-
-
-
-[endsect]
-
-
-
-[section:overload5 buffer_size (5 of 5 overloads)]
-
-
-Get the total number of bytes in a buffer sequence. 
-
-
-  template<
-      typename BufferSequence>
-  std::size_t buffer_size(
-      const BufferSequence & b,
-      typename enable_if< is_const_buffer_sequence< BufferSequence >::value >::type *  = 0);
-
-
-The `BufferSequence` template parameter may meet either of the `ConstBufferSequence` or `MutableBufferSequence` type requirements. 
-
-
-[endsect]
-
-
-[endsect]
-
 [section:buffered_read_stream buffered_read_stream]
 
 
diff --git a/asio/src/tests/unit/buffer.cpp b/asio/src/tests/unit/buffer.cpp
index af749de..c0060d0 100644
--- a/asio/src/tests/unit/buffer.cpp
+++ b/asio/src/tests/unit/buffer.cpp
@@ -307,8 +307,216 @@
 
 //------------------------------------------------------------------------------
 
+namespace buffer_copy_runtime {
+
+using namespace asio;
+using namespace std;
+
+void test()
+{
+  char dest_data[256];
+  char source_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mutable_buffer mb1 = asio::buffer(dest_data);
+  mutable_buffer mb2 = asio::buffer(source_data);
+  std::size_t n = buffer_copy(mb1, mb2);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  const_buffer cb1 = asio::buffer(source_data);
+  n = buffer_copy(mb1, cb1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+#if !defined(ASIO_NO_DEPRECATED)
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  mutable_buffers_1 mbc1 = asio::buffer(source_data);
+  n = buffer_copy(mb1, mbc1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  const_buffers_1 cbc1 = const_buffers_1(asio::buffer(source_data));
+  n = buffer_copy(mb1, cbc1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  mb1 = asio::buffer(source_data);
+  n = buffer_copy(mbc1, mb1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  cb1 = asio::buffer(source_data);
+  n = buffer_copy(mbc1, cb1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  mutable_buffers_1 mbc2 = asio::buffer(source_data);
+  n = buffer_copy(mbc1, mbc2);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  cbc1 = const_buffers_1(asio::buffer(source_data));
+  n = buffer_copy(mbc1, cbc1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  std::vector<mutable_buffer> mv1;
+  mv1.push_back(asio::buffer(source_data, 5));
+  mv1.push_back(asio::buffer(source_data) + 5);
+  n = buffer_copy(mb1, mv1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  std::vector<const_buffer> cv1;
+  cv1.push_back(asio::buffer(source_data, 6));
+  cv1.push_back(asio::buffer(source_data) + 6);
+  n = buffer_copy(mb1, cv1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mv1.clear();
+  mv1.push_back(asio::buffer(dest_data, 7));
+  mv1.push_back(asio::buffer(dest_data) + 7);
+  cb1 = asio::buffer(source_data);
+  n = buffer_copy(mv1, cb1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mv1.clear();
+  mv1.push_back(asio::buffer(dest_data, 7));
+  mv1.push_back(asio::buffer(dest_data) + 7);
+  cv1.clear();
+  cv1.push_back(asio::buffer(source_data, 8));
+  cv1.push_back(asio::buffer(source_data) + 8);
+  n = buffer_copy(mv1, cv1);
+  ASIO_CHECK(n == sizeof(source_data));
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  mb2 = asio::buffer(source_data);
+  n = buffer_copy(mb1, mb2, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  cb1 = asio::buffer(source_data);
+  n = buffer_copy(mb1, cb1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+#if !defined(ASIO_NO_DEPRECATED)
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  mbc1 = asio::buffer(source_data);
+  n = buffer_copy(mb1, mbc1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  cbc1 = const_buffers_1(asio::buffer(source_data));
+  n = buffer_copy(mb1, cbc1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  mb1 = asio::buffer(source_data);
+  n = buffer_copy(mbc1, mb1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  cb1 = asio::buffer(source_data);
+  n = buffer_copy(mbc1, cb1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  mbc2 = asio::buffer(source_data);
+  n = buffer_copy(mbc1, mbc2, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mbc1 = asio::buffer(dest_data);
+  cbc1 = const_buffers_1(asio::buffer(source_data));
+  n = buffer_copy(mbc1, cbc1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+#endif // !defined(ASIO_NO_DEPRECATED)
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  mv1.clear();
+  mv1.push_back(asio::buffer(source_data, 5));
+  mv1.push_back(asio::buffer(source_data) + 5);
+  n = buffer_copy(mb1, mv1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mb1 = asio::buffer(dest_data);
+  cv1.clear();
+  cv1.push_back(asio::buffer(source_data, 6));
+  cv1.push_back(asio::buffer(source_data) + 6);
+  n = buffer_copy(mb1, cv1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mv1.clear();
+  mv1.push_back(asio::buffer(dest_data, 7));
+  mv1.push_back(asio::buffer(dest_data) + 7);
+  cb1 = asio::buffer(source_data);
+  n = buffer_copy(mv1, cb1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+
+  memset(dest_data, 0, sizeof(dest_data));
+  mv1.clear();
+  mv1.push_back(asio::buffer(dest_data, 7));
+  mv1.push_back(asio::buffer(dest_data) + 7);
+  cv1.clear();
+  cv1.push_back(asio::buffer(source_data, 8));
+  cv1.push_back(asio::buffer(source_data) + 8);
+  n = buffer_copy(mv1, cv1, 10);
+  ASIO_CHECK(n == 10);
+  ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
+}
+
+} // namespace buffer_copy_runtime
+
+//------------------------------------------------------------------------------
+
 ASIO_TEST_SUITE
 (
   "buffer",
   ASIO_COMPILE_TEST_CASE(buffer_compile::test)
+  ASIO_TEST_CASE(buffer_copy_runtime::test)
 )