summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/asio/buffer.hpp')
-rw-r--r--3rdParty/Boost/src/boost/asio/buffer.hpp1348
1 files changed, 1223 insertions, 125 deletions
diff --git a/3rdParty/Boost/src/boost/asio/buffer.hpp b/3rdParty/Boost/src/boost/asio/buffer.hpp
index 15eaad4..532cfd1 100644
--- a/3rdParty/Boost/src/boost/asio/buffer.hpp
+++ b/3rdParty/Boost/src/boost/asio/buffer.hpp
@@ -2,7 +2,7 @@
// buffer.hpp
// ~~~~~~~~~~
//
-// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -17,6 +17,7 @@
#include <boost/asio/detail/config.hpp>
#include <cstddef>
+#include <cstring>
#include <string>
#include <vector>
#include <boost/detail/workaround.hpp>
@@ -68,6 +69,19 @@ std::size_t buffer_size_helper(const const_buffer&);
* The mutable_buffer class provides a safe representation of a buffer that can
* be modified. It does not own the underlying data, and so is cheap to copy or
* assign.
+ *
+ * @par Accessing Buffer Contents
+ *
+ * The contents of a buffer may be accessed using the @ref buffer_size
+ * and @ref buffer_cast functions:
+ *
+ * @code boost::asio::mutable_buffer b1 = ...;
+ * std::size_t s1 = boost::asio::buffer_size(b1);
+ * unsigned char* p1 = boost::asio::buffer_cast<unsigned char*>(b1);
+ * @endcode
+ *
+ * The boost::asio::buffer_cast function permits violations of type safety, so
+ * uses of it in application code should be carefully considered.
*/
class mutable_buffer
{
@@ -133,59 +147,6 @@ inline std::size_t buffer_size_helper(const mutable_buffer& b)
} // namespace detail
-/// Cast a non-modifiable buffer to a specified pointer to POD type.
-/**
- * @relates mutable_buffer
- */
-template <typename PointerToPodType>
-inline PointerToPodType buffer_cast(const mutable_buffer& b)
-{
- return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
-}
-
-/// Get the number of bytes in a non-modifiable buffer.
-/**
- * @relates mutable_buffer
- */
-inline std::size_t buffer_size(const mutable_buffer& b)
-{
- return detail::buffer_size_helper(b);
-}
-
-/// Create a new modifiable buffer that is offset from the start of another.
-/**
- * @relates mutable_buffer
- */
-inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
-{
- if (start > buffer_size(b))
- return mutable_buffer();
- char* new_data = buffer_cast<char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
- return mutable_buffer(new_data, new_size
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , b.get_debug_check()
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- );
-}
-
-/// Create a new modifiable buffer that is offset from the start of another.
-/**
- * @relates mutable_buffer
- */
-inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
-{
- if (start > buffer_size(b))
- return mutable_buffer();
- char* new_data = buffer_cast<char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
- return mutable_buffer(new_data, new_size
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , b.get_debug_check()
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- );
-}
-
/// Adapts a single modifiable buffer so that it meets the requirements of the
/// MutableBufferSequence concept.
class mutable_buffers_1
@@ -228,6 +189,19 @@ public:
* The const_buffer class provides a safe representation of a buffer that cannot
* be modified. It does not own the underlying data, and so is cheap to copy or
* assign.
+ *
+ * @par Accessing Buffer Contents
+ *
+ * The contents of a buffer may be accessed using the @ref buffer_size
+ * and @ref buffer_cast functions:
+ *
+ * @code boost::asio::const_buffer b1 = ...;
+ * std::size_t s1 = boost::asio::buffer_size(b1);
+ * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
+ * @endcode
+ *
+ * The boost::asio::buffer_cast function permits violations of type safety, so
+ * uses of it in application code should be carefully considered.
*/
class const_buffer
{
@@ -303,59 +277,6 @@ inline std::size_t buffer_size_helper(const const_buffer& b)
} // namespace detail
-/// Cast a non-modifiable buffer to a specified pointer to POD type.
-/**
- * @relates const_buffer
- */
-template <typename PointerToPodType>
-inline PointerToPodType buffer_cast(const const_buffer& b)
-{
- return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
-}
-
-/// Get the number of bytes in a non-modifiable buffer.
-/**
- * @relates const_buffer
- */
-inline std::size_t buffer_size(const const_buffer& b)
-{
- return detail::buffer_size_helper(b);
-}
-
-/// Create a new non-modifiable buffer that is offset from the start of another.
-/**
- * @relates const_buffer
- */
-inline const_buffer operator+(const const_buffer& b, std::size_t start)
-{
- if (start > buffer_size(b))
- return const_buffer();
- const char* new_data = buffer_cast<const char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
- return const_buffer(new_data, new_size
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , b.get_debug_check()
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- );
-}
-
-/// Create a new non-modifiable buffer that is offset from the start of another.
-/**
- * @relates const_buffer
- */
-inline const_buffer operator+(std::size_t start, const const_buffer& b)
-{
- if (start > buffer_size(b))
- return const_buffer();
- const char* new_data = buffer_cast<const char*>(b) + start;
- std::size_t new_size = buffer_size(b) - start;
- return const_buffer(new_data, new_size
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , b.get_debug_check()
-#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
- );
-}
-
/// Adapts a single non-modifiable buffer so that it meets the requirements of
/// the ConstBufferSequence concept.
class const_buffers_1
@@ -420,6 +341,163 @@ private:
mutable_buffer buf_;
};
+/** @defgroup buffer_size boost::asio::buffer_size
+ *
+ * @brief The boost::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)
+{
+ return detail::buffer_size_helper(b);
+}
+
+/// Get the number of bytes in a modifiable buffer.
+inline std::size_t buffer_size(const mutable_buffers_1& b)
+{
+ return detail::buffer_size_helper(b);
+}
+
+/// Get the number of bytes in a non-modifiable buffer.
+inline std::size_t buffer_size(const const_buffer& b)
+{
+ return detail::buffer_size_helper(b);
+}
+
+/// Get the number of bytes in a non-modifiable buffer.
+inline std::size_t buffer_size(const const_buffers_1& b)
+{
+ return detail::buffer_size_helper(b);
+}
+
+/// Get the total number of bytes in a buffer sequence.
+/**
+ * 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)
+{
+ std::size_t total_buffer_size = 0;
+
+ typename BufferSequence::const_iterator iter = b.begin();
+ typename BufferSequence::const_iterator end = b.end();
+ for (; iter != end; ++iter)
+ total_buffer_size += detail::buffer_size_helper(*iter);
+
+ return total_buffer_size;
+}
+
+/*@}*/
+
+/** @defgroup buffer_cast boost::asio::buffer_cast
+ *
+ * @brief The boost::asio::buffer_cast function is used to obtain a pointer to
+ * the underlying memory region associated with a buffer.
+ *
+ * @par Examples:
+ *
+ * To access the memory of a non-modifiable buffer, use:
+ * @code boost::asio::const_buffer b1 = ...;
+ * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
+ * @endcode
+ *
+ * To access the memory of a modifiable buffer, use:
+ * @code boost::asio::mutable_buffer b2 = ...;
+ * unsigned char* p2 = boost::asio::buffer_cast<unsigned char*>(b2);
+ * @endcode
+ *
+ * The boost::asio::buffer_cast function permits violations of type safety, so
+ * uses of it in application code should be carefully considered.
+ */
+/*@{*/
+
+/// Cast a non-modifiable buffer to a specified pointer to POD type.
+template <typename PointerToPodType>
+inline PointerToPodType buffer_cast(const mutable_buffer& b)
+{
+ return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
+}
+
+/// Cast a non-modifiable buffer to a specified pointer to POD type.
+template <typename PointerToPodType>
+inline PointerToPodType buffer_cast(const const_buffer& b)
+{
+ return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
+}
+
+/*@}*/
+
+/// Create a new modifiable buffer that is offset from the start of another.
+/**
+ * @relates mutable_buffer
+ */
+inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
+{
+ if (start > buffer_size(b))
+ return mutable_buffer();
+ char* new_data = buffer_cast<char*>(b) + start;
+ std::size_t new_size = buffer_size(b) - start;
+ return mutable_buffer(new_data, new_size
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
+}
+
+/// Create a new modifiable buffer that is offset from the start of another.
+/**
+ * @relates mutable_buffer
+ */
+inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
+{
+ if (start > buffer_size(b))
+ return mutable_buffer();
+ char* new_data = buffer_cast<char*>(b) + start;
+ std::size_t new_size = buffer_size(b) - start;
+ return mutable_buffer(new_data, new_size
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
+}
+
+/// Create a new non-modifiable buffer that is offset from the start of another.
+/**
+ * @relates const_buffer
+ */
+inline const_buffer operator+(const const_buffer& b, std::size_t start)
+{
+ if (start > buffer_size(b))
+ return const_buffer();
+ const char* new_data = buffer_cast<const char*>(b) + start;
+ std::size_t new_size = buffer_size(b) - start;
+ return const_buffer(new_data, new_size
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
+}
+
+/// Create a new non-modifiable buffer that is offset from the start of another.
+/**
+ * @relates const_buffer
+ */
+inline const_buffer operator+(std::size_t start, const const_buffer& b)
+{
+ if (start > buffer_size(b))
+ return const_buffer();
+ const char* new_data = buffer_cast<const char*>(b) + start;
+ std::size_t new_size = buffer_size(b) - start;
+ return const_buffer(new_data, new_size
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+ );
+}
+
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
namespace detail {
@@ -479,9 +557,9 @@ private:
* passed to the socket's write function. A buffer created for modifiable
* memory also meets the requirements of the MutableBufferSequence concept.
*
- * An individual buffer may be created from a builtin array, std::vector or
- * boost::array of POD elements. This helps prevent buffer overruns by
- * automatically determining the size of the buffer:
+ * An individual buffer may be created from a builtin array, std::vector,
+ * std::array or boost::array of POD elements. This helps prevent buffer
+ * overruns by automatically determining the size of the buffer:
*
* @code char d1[128];
* size_t bytes_transferred = sock.receive(boost::asio::buffer(d1));
@@ -489,8 +567,11 @@ private:
* std::vector<char> d2(128);
* bytes_transferred = sock.receive(boost::asio::buffer(d2));
*
- * boost::array<char, 128> d3;
- * bytes_transferred = sock.receive(boost::asio::buffer(d3)); @endcode
+ * std::array<char, 128> d3;
+ * bytes_transferred = sock.receive(boost::asio::buffer(d3));
+ *
+ * boost::array<char, 128> d4;
+ * bytes_transferred = sock.receive(boost::asio::buffer(d4)); @endcode
*
* In all three cases above, the buffers created are exactly 128 bytes long.
* Note that a vector is @e never automatically resized when creating or using
@@ -499,8 +580,8 @@ private:
*
* @par Accessing Buffer Contents
*
- * The contents of a buffer may be accessed using the boost::asio::buffer_size
- * and boost::asio::buffer_cast functions:
+ * The contents of a buffer may be accessed using the @ref buffer_size and
+ * @ref buffer_cast functions:
*
* @code boost::asio::mutable_buffer b1 = ...;
* std::size_t s1 = boost::asio::buffer_size(b1);
@@ -513,6 +594,24 @@ private:
* The boost::asio::buffer_cast function permits violations of type safety, so
* uses of it in application code should be carefully considered.
*
+ * For convenience, the @ref buffer_size function also works on buffer
+ * sequences (that is, types meeting the ConstBufferSequence or
+ * MutableBufferSequence type requirements). In this case, the function returns
+ * the total size of all buffers in the sequence.
+ *
+ * @par Buffer Copying
+ *
+ * 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:
+ *
+ * @code vector<const_buffer> buffers = ...;
+ *
+ * vector<unsigned char> data(boost::asio::buffer_size(buffers));
+ * boost::asio::buffer_copy(boost::asio::buffer(data), buffers); @endcode
+ *
* @par Buffer Invalidation
*
* A buffer object does not have any ownership of the memory it refers to. It
@@ -526,8 +625,8 @@ private:
* referring to the elements in the sequence (C++ Std, 23.2.4)
*
* For the boost::asio::buffer overloads that accept an argument of type
- * std::string, the buffer objects returned are invalidated according to the
- * rules defined for invalidation of references, pointers and iterators
+ * std::basic_string, the buffer objects returned are invalidated according to
+ * the rules defined for invalidation of references, pointers and iterators
* referring to elements of the sequence (C++ Std, 21.3).
*
* @par Buffer Arithmetic
@@ -896,6 +995,103 @@ inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
? data.size() * sizeof(PodType) : max_size_in_bytes));
}
+#if defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
+
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffers_1 value equivalent to:
+ * @code mutable_buffers_1(
+ * data.data(),
+ * data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline mutable_buffers_1 buffer(std::array<PodType, N>& data)
+{
+ return mutable_buffers_1(
+ mutable_buffer(data.data(), data.size() * sizeof(PodType)));
+}
+
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffers_1 value equivalent to:
+ * @code mutable_buffers_1(
+ * data.data(),
+ * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline mutable_buffers_1 buffer(std::array<PodType, N>& data,
+ std::size_t max_size_in_bytes)
+{
+ return mutable_buffers_1(
+ mutable_buffer(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffers_1 value equivalent to:
+ * @code const_buffers_1(
+ * data.data(),
+ * data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline const_buffers_1 buffer(std::array<const PodType, N>& data)
+{
+ return const_buffers_1(
+ const_buffer(data.data(), data.size() * sizeof(PodType)));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffers_1 value equivalent to:
+ * @code const_buffers_1(
+ * data.data(),
+ * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline const_buffers_1 buffer(std::array<const PodType, N>& data,
+ std::size_t max_size_in_bytes)
+{
+ return const_buffers_1(
+ const_buffer(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffers_1 value equivalent to:
+ * @code const_buffers_1(
+ * data.data(),
+ * data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline const_buffers_1 buffer(const std::array<PodType, N>& data)
+{
+ return const_buffers_1(
+ const_buffer(data.data(), data.size() * sizeof(PodType)));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffers_1 value equivalent to:
+ * @code const_buffers_1(
+ * data.data(),
+ * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline const_buffers_1 buffer(const std::array<PodType, N>& data,
+ std::size_t max_size_in_bytes)
+{
+ return const_buffers_1(
+ const_buffer(data.data(),
+ data.size() * sizeof(PodType) < max_size_in_bytes
+ ? data.size() * sizeof(PodType) : max_size_in_bytes));
+}
+
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
+
/// Create a new modifiable buffer that represents the given POD vector.
/**
* @returns A mutable_buffers_1 value equivalent to:
@@ -997,16 +1193,20 @@ inline const_buffers_1 buffer(
/// Create a new non-modifiable buffer that represents the given string.
/**
- * @returns <tt>const_buffers_1(data.data(), data.size())</tt>.
+ * @returns <tt>const_buffers_1(data.data(), data.size() * sizeof(Elem))</tt>.
*
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
-inline const_buffers_1 buffer(const std::string& data)
+template <typename Elem, typename Traits, typename Allocator>
+inline const_buffers_1 buffer(
+ const std::basic_string<Elem, Traits, Allocator>& data)
{
- return const_buffers_1(const_buffer(data.data(), data.size()
+ return const_buffers_1(const_buffer(data.data(), data.size() * sizeof(Elem)
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<std::string::const_iterator>(data.begin())
+ , detail::buffer_debug_check<
+ typename std::basic_string<Elem, Traits, Allocator>::const_iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
));
}
@@ -1016,26 +1216,924 @@ inline const_buffers_1 buffer(const std::string& data)
* @returns A const_buffers_1 value equivalent to:
* @code const_buffers_1(
* data.data(),
- * min(data.size(), max_size_in_bytes)); @endcode
+ * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
*
* @note The buffer is invalidated by any non-const operation called on the
* given string object.
*/
-inline const_buffers_1 buffer(const std::string& data,
+template <typename Elem, typename Traits, typename Allocator>
+inline const_buffers_1 buffer(
+ const std::basic_string<Elem, Traits, Allocator>& data,
std::size_t max_size_in_bytes)
{
return const_buffers_1(
const_buffer(data.data(),
- data.size() < max_size_in_bytes
- ? data.size() : max_size_in_bytes
+ data.size() * sizeof(Elem) < max_size_in_bytes
+ ? data.size() * sizeof(Elem) : max_size_in_bytes
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- , detail::buffer_debug_check<std::string::const_iterator>(data.begin())
+ , detail::buffer_debug_check<
+ typename std::basic_string<Elem, Traits, Allocator>::const_iterator
+ >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
));
}
/*@}*/
+/** @defgroup buffer_copy boost::asio::buffer_copy
+ *
+ * @brief The boost::asio::buffer_copy function is used to copy bytes from a
+ * source buffer (or buffer sequence) to a target buffer (or buffer sequence).
+ *
+ * The @c buffer_copy function is available in two forms:
+ *
+ * @li A 2-argument form: @c buffer_copy(target, source)
+ *
+ * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy)
+
+ * Both forms return the number of bytes actually copied. The number of bytes
+ * copied is the lesser of:
+ *
+ * @li @c buffer_size(target)
+ *
+ * @li @c buffer_size(source)
+ *
+ * @li @c If specified, @c max_bytes_to_copy.
+ *
+ * This prevents buffer overflow, regardless of the buffer sizes used in the
+ * copy operation.
+ */
+/*@{*/
+
+/// 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)
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const const_buffer& source)
+{
+ using namespace std; // For memcpy.
+ std::size_t target_size = buffer_size(target);
+ std::size_t source_size = buffer_size(source);
+ std::size_t n = target_size < source_size ? target_size : source_size;
+ memcpy(buffer_cast<void*>(target), buffer_cast<const void*>(source), n);
+ return n;
+}
+
+/// 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)
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const const_buffers_1& source)
+{
+ return buffer_copy(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)
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const mutable_buffer& source)
+{
+ return buffer_copy(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)
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const mutable_buffers_1& source)
+{
+ return buffer_copy(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)
+ */
+template <typename ConstBufferSequence>
+std::size_t buffer_copy(const mutable_buffer& target,
+ const ConstBufferSequence& source)
+{
+ std::size_t total_bytes_copied = 0;
+
+ typename ConstBufferSequence::const_iterator source_iter = source.begin();
+ typename ConstBufferSequence::const_iterator source_end = source.end();
+
+ for (mutable_buffer target_buffer(target);
+ buffer_size(target_buffer) && source_iter != source_end; ++source_iter)
+ {
+ const_buffer source_buffer(*source_iter);
+ std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
+ total_bytes_copied += bytes_copied;
+ target_buffer = target_buffer + bytes_copied;
+ }
+
+ return total_bytes_copied;
+}
+
+/// 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)
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const const_buffer& source)
+{
+ 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)
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const const_buffers_1& source)
+{
+ 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)
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const mutable_buffer& source)
+{
+ 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)
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const mutable_buffers_1& source)
+{
+ 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)
+ */
+template <typename ConstBufferSequence>
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const ConstBufferSequence& source)
+{
+ return buffer_copy(static_cast<const mutable_buffer&>(target), source);
+}
+
+/// 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)
+ */
+template <typename MutableBufferSequence>
+std::size_t buffer_copy(const MutableBufferSequence& target,
+ const const_buffer& source)
+{
+ std::size_t total_bytes_copied = 0;
+
+ typename MutableBufferSequence::const_iterator target_iter = target.begin();
+ typename MutableBufferSequence::const_iterator target_end = target.end();
+
+ for (const_buffer source_buffer(source);
+ buffer_size(source_buffer) && target_iter != target_end; ++target_iter)
+ {
+ mutable_buffer target_buffer(*target_iter);
+ std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
+ total_bytes_copied += bytes_copied;
+ source_buffer = source_buffer + bytes_copied;
+ }
+
+ return total_bytes_copied;
+}
+
+/// 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)
+ */
+template <typename MutableBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const const_buffers_1& source)
+{
+ return buffer_copy(target, static_cast<const const_buffer&>(source));
+}
+
+/// 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)
+ */
+template <typename MutableBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const mutable_buffer& source)
+{
+ return buffer_copy(target, const_buffer(source));
+}
+
+/// 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)
+ */
+template <typename MutableBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const mutable_buffers_1& source)
+{
+ return buffer_copy(target, const_buffer(source));
+}
+
+/// Copies bytes from a source buffer sequence 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 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)
+ */
+template <typename MutableBufferSequence, typename ConstBufferSequence>
+std::size_t buffer_copy(const MutableBufferSequence& target,
+ const ConstBufferSequence& source)
+{
+ std::size_t total_bytes_copied = 0;
+
+ typename MutableBufferSequence::const_iterator target_iter = target.begin();
+ typename MutableBufferSequence::const_iterator target_end = target.end();
+ std::size_t target_buffer_offset = 0;
+
+ typename ConstBufferSequence::const_iterator source_iter = source.begin();
+ typename ConstBufferSequence::const_iterator source_end = source.end();
+ std::size_t source_buffer_offset = 0;
+
+ while (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);
+ total_bytes_copied += bytes_copied;
+
+ if (bytes_copied == buffer_size(target_buffer))
+ {
+ ++target_iter;
+ target_buffer_offset = 0;
+ }
+ else
+ target_buffer_offset += bytes_copied;
+
+ if (bytes_copied == buffer_size(source_buffer))
+ {
+ ++source_iter;
+ source_buffer_offset = 0;
+ }
+ else
+ source_buffer_offset += bytes_copied;
+ }
+
+ return total_bytes_copied;
+}
+
+/// 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
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const const_buffer& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const const_buffers_1& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const mutable_buffer& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+template <typename ConstBufferSequence>
+inline std::size_t buffer_copy(const mutable_buffer& target,
+ const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const const_buffer& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const const_buffers_1& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const mutable_buffer& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
+{
+ 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
+ */
+template <typename ConstBufferSequence>
+inline std::size_t buffer_copy(const mutable_buffers_1& target,
+ const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
+{
+ return buffer_copy(buffer(target, max_bytes_to_copy), source);
+}
+
+/// 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
+ */
+template <typename MutableBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const const_buffer& source, std::size_t max_bytes_to_copy)
+{
+ return buffer_copy(target, buffer(source, max_bytes_to_copy));
+}
+
+/// 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
+ */
+template <typename MutableBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const const_buffers_1& source, std::size_t max_bytes_to_copy)
+{
+ return buffer_copy(target, buffer(source, max_bytes_to_copy));
+}
+
+/// 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
+ */
+template <typename MutableBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const mutable_buffer& source, std::size_t max_bytes_to_copy)
+{
+ return buffer_copy(target, buffer(source, max_bytes_to_copy));
+}
+
+/// 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
+ */
+template <typename MutableBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+ const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
+{
+ return buffer_copy(target, buffer(source, max_bytes_to_copy));
+}
+
+/// Copies a limited number of bytes from a source buffer sequence 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 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
+ */
+template <typename MutableBufferSequence, typename ConstBufferSequence>
+std::size_t buffer_copy(const MutableBufferSequence& target,
+ const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
+{
+ std::size_t total_bytes_copied = 0;
+
+ typename MutableBufferSequence::const_iterator target_iter = target.begin();
+ typename MutableBufferSequence::const_iterator target_end = target.end();
+ std::size_t target_buffer_offset = 0;
+
+ typename ConstBufferSequence::const_iterator source_iter = source.begin();
+ typename ConstBufferSequence::const_iterator source_end = source.end();
+ 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 == buffer_size(target_buffer))
+ {
+ ++target_iter;
+ target_buffer_offset = 0;
+ }
+ else
+ target_buffer_offset += bytes_copied;
+
+ if (bytes_copied == buffer_size(source_buffer))
+ {
+ ++source_iter;
+ source_buffer_offset = 0;
+ }
+ else
+ source_buffer_offset += bytes_copied;
+ }
+
+ return total_bytes_copied;
+}
+
+/*@}*/
+
} // namespace asio
} // namespace boost