/**
\page designbuffers Buffers

To allow the development of efficient network applications, the asio library
provides support for scatter-gather operations. These operations involve one or
more buffers (where each buffer is a contiguous region of memory):

\li A <b>scatter-read</b> receives data into multiple buffers.
\li A <b>gather-write</b> transmits multiple buffers.

Therefore we require an abstraction to represent a collection of buffers. The
approach asio uses is to define a type (actually two types) to represent a
single buffer. These can be stored in a container, which may be passed to the
scatter-gather operations.

A buffer, as a contiguous region of memory, can be represented by an address
and size in bytes. There is a distinction between modifiable memory (called
mutable in asio) and non-modifiable memory (where the latter is created from
the storage for a const-qualified variable). These two types could therefore be
defined as follows:

\code
typedef std::pair<void*, std::size_t> mutable_buffer;
typedef std::pair<const void*, std::size_t> const_buffer;
\endcode

Here, a mutable_buffer would be convertible to a const_buffer, but conversion
in the opposite direction is not valid.

However, the asio library does not use the above definitions, but instead
defines two classes: boost::asio::mutable_buffer and boost::asio::const_buffer. The goal of
these is to provide an opaque representation of contiguous memory, where:

\li Types behave as std::pair would in conversions. That is, a mutable_buffer is
convertible to a const_buffer, but the opposite conversion is disallowed.
\li There is protection against buffer overruns. Given a buffer instance, a
user can only create another buffer representing the same range of memory or a
sub-range of it. To provide further safety, the library also includes
mechanisms for automatically determining the size of a buffer from an array,
boost::array or std::vector of POD elements.
\li Type safety violations must be explicitly requested using the
boost::asio::buffer_cast function. In general an application should never need to do
this, but it is required by the asio implementation to pass the raw memory to
the underlying operating system functions.

Finally, multiple buffers can be passed to scatter-gather operations (such as
\ref read or \ref write) by putting the buffer objects into a container. The
Mutable_Buffers and Const_Buffers concepts have been defined so that containers
such as std::vector, std::list, std::vector or boost::array can be used. See
the documentation for \ref buffer for examples.

*/
