Skip to content

Commit

Permalink
Allow buffers to be implicitly constructed from spans.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskohlhoff committed Oct 21, 2024
1 parent 31b0635 commit 645efa7
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 11 deletions.
40 changes: 40 additions & 0 deletions asio/include/asio/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,26 @@ class mutable_buffer
{
}

/// Construct a buffer from a span of bytes.
template <template <typename, std::size_t> class Span,
typename T, std::size_t Extent>
mutable_buffer(const Span<T, Extent>& span,
constraint_t<
sizeof(T) == 1,
defaulted_constraint
> = defaulted_constraint(),
constraint_t<
is_same<
decltype(as_writable_bytes(span)),
Span<T, Extent>
>::value,
defaulted_constraint
> = defaulted_constraint())
: data_(span.data()),
size_(span.size())
{
}

#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
mutable_buffer(void* data, std::size_t size,
asio::detail::function<void()> debug_check)
Expand Down Expand Up @@ -187,6 +207,26 @@ class const_buffer
{
}

/// Construct a buffer from a span of bytes.
template <template <typename, std::size_t> class Span,
typename T, std::size_t Extent>
const_buffer(const Span<T, Extent>& span,
constraint_t<
sizeof(T) == 1,
defaulted_constraint
> = defaulted_constraint(),
constraint_t<
is_same<
decltype(as_bytes(span)),
Span<add_const_t<T>, Extent>
>::value,
defaulted_constraint
> = defaulted_constraint())
: data_(span.data()),
size_(span.size())
{
}

#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
const_buffer(const void* data, std::size_t size,
asio::detail::function<void()> debug_check)
Expand Down
5 changes: 5 additions & 0 deletions asio/include/asio/detail/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ using std::is_same;

using std::is_scalar;

using std::remove_const;

template <typename T>
using remove_const_t = typename std::remove_const<T>::type;

using std::remove_cv;

template <typename T>
Expand Down
47 changes: 36 additions & 11 deletions asio/src/tests/unit/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ class const_contiguous_container
const_iterator end() const { return 0; }
};

template <typename T, std::size_t Extent>
struct span
{
T* data() const { return 0; }
std::size_t size() const { return 0; }
friend span<const T, Extent> as_bytes(const span&) { return {}; }
friend span as_writable_bytes(const span&) { return {}; }
};

template <typename T, std::size_t Extent>
struct span<const T, Extent>
{
T* data() const { return 0; }
std::size_t size() const { return 0; }
friend span as_bytes(const span&) { return {}; }
};

void test()
{
try
Expand All @@ -79,6 +96,8 @@ void test()
const char const_raw_data[1024] = "";
void* void_ptr_data = raw_data;
const void* const_void_ptr_data = const_raw_data;
span<char, 1> span_1;
span<const char, 1> span_2;
#if defined(ASIO_HAS_BOOST_ARRAY)
boost::array<char, 1024> array_data;
const boost::array<char, 1024>& const_array_data_1 = array_data;
Expand Down Expand Up @@ -107,8 +126,10 @@ void test()

mutable_buffer mb1;
mutable_buffer mb2(void_ptr_data, 1024);
mutable_buffer mb3(mb1);
mutable_buffer mb3(span_1);
(void)mb3;
mutable_buffer mb4(mb1);
(void)mb4;

// mutable_buffer functions.

Expand All @@ -128,10 +149,14 @@ void test()

const_buffer cb1;
const_buffer cb2(const_void_ptr_data, 1024);
const_buffer cb3(cb1);
const_buffer cb3(span_1);
(void)cb3;
const_buffer cb4(mb1);
const_buffer cb4(span_2);
(void)cb4;
const_buffer cb5(cb1);
(void)cb5;
const_buffer cb6(mb1);
(void)cb6;

// const_buffer functions.

Expand Down Expand Up @@ -264,11 +289,11 @@ void test()
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type>::const_buffers_type
cb5 = db1.data();
(void)cb5;
cb7 = db1.data();
(void)cb7;
dynamic_vector_buffer<char, std::allocator<char> >::const_buffers_type
cb6 = db3.data();
(void)cb6;
cb8 = db3.data();
(void)cb8;

dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type>::mutable_buffers_type mb5
Expand All @@ -292,14 +317,14 @@ void test()

dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type>::const_buffers_type
cb7 = static_cast<const dynamic_string_buffer<char,
cb9 = static_cast<const dynamic_string_buffer<char,
std::string::traits_type,
std::string::allocator_type>&>(db1).data(0, 1);
(void)cb7;
(void)cb9;
dynamic_vector_buffer<char, std::allocator<char> >::const_buffers_type
cb8 = static_cast<const dynamic_vector_buffer<char,
cb10 = static_cast<const dynamic_vector_buffer<char,
std::allocator<char> >&>(db3).data(0, 1);
(void)cb8;
(void)cb10;

db1.grow(1024);
db3.grow(1024);
Expand Down

0 comments on commit 645efa7

Please sign in to comment.