Add asio::buffer() overloads for std::array.

This commit is contained in:
Christopher Kohlhoff 2011-03-17 13:39:13 +11:00
parent 344b6f19d8
commit be04109a7b
4 changed files with 144 additions and 6 deletions

View File

@ -556,9 +556,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(asio::buffer(d1));
@ -566,8 +566,11 @@ private:
* std::vector<char> d2(128);
* bytes_transferred = sock.receive(asio::buffer(d2));
*
* boost::array<char, 128> d3;
* bytes_transferred = sock.receive(asio::buffer(d3)); @endcode
* std::array<char, 128> d3;
* bytes_transferred = sock.receive(asio::buffer(d3));
*
* boost::array<char, 128> d4;
* bytes_transferred = sock.receive(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
@ -973,6 +976,103 @@ inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
? data.size() * sizeof(PodType) : max_size_in_bytes));
}
#if defined(ASIO_HAS_STD_ARRAY)
/// 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(ASIO_HAS_STD_ARRAY)
/// Create a new modifiable buffer that represents the given POD vector.
/**
* @returns A mutable_buffers_1 value equivalent to:

View File

@ -15,6 +15,8 @@
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
namespace boost {
template<class T, std::size_t N>
@ -22,4 +24,11 @@ class array;
} // namespace boost
// Standard library components can't be forward declared, so we'll have to
// include the array header. Fortunately, it's fairly lightweight and doesn't
// add significantly to the compile time.
#if defined(ASIO_HAS_STD_ARRAY)
# include <array>
#endif // defined(ASIO_HAS_STD_ARRAY)
#endif // ASIO_DETAIL_ARRAY_FWD_HPP

View File

@ -76,10 +76,26 @@
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define ASIO_HAS_STD_SYSTEM_ERROR
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
#endif // !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)
// Standard library support for arrays.
#if !defined(ASIO_DISABLE_STD_ARRAY)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define ASIO_HAS_STD_ARRAY
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_MSVC)
# if (_MSC_VER >= 1600)
# define ASIO_HAS_STD_ARRAY
# endif // (_MSC_VER >= 1600)
# endif // defined(BOOST_MSVC)
#endif // !defined(ASIO_DISABLE_STD_ARRAY)
// Windows: target OS version.
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)

View File

@ -41,6 +41,11 @@ void test()
boost::array<char, 1024> array_data;
const boost::array<char, 1024>& const_array_data_1 = array_data;
boost::array<const char, 1024> const_array_data_2 = { { 0 } };
#if defined(ASIO_HAS_STD_ARRAY)
std::array<char, 1024> std_array_data;
const std::array<char, 1024>& const_std_array_data_1 = std_array_data;
std::array<const char, 1024> const_std_array_data_2 = { { 0 } };
#endif // defined(ASIO_HAS_STD_ARRAY)
std::vector<char> vector_data(1024);
const std::vector<char>& const_vector_data = vector_data;
const std::string string_data(1024, ' ');
@ -134,6 +139,14 @@ void test()
cb1 = buffer(const_array_data_1, 1024);
cb1 = buffer(const_array_data_2);
cb1 = buffer(const_array_data_2, 1024);
#if defined(ASIO_HAS_STD_ARRAY)
mb1 = buffer(std_array_data);
mb1 = buffer(std_array_data, 1024);
cb1 = buffer(const_std_array_data_1);
cb1 = buffer(const_std_array_data_1, 1024);
cb1 = buffer(const_std_array_data_2);
cb1 = buffer(const_std_array_data_2, 1024);
#endif // defined(ASIO_HAS_STD_ARRAY)
mb1 = buffer(vector_data);
mb1 = buffer(vector_data, 1024);
cb1 = buffer(const_vector_data);