Skip to content

Commit

Permalink
Add buffer_sequence_begin/end overloads for types that are convertibl…
Browse files Browse the repository at this point in the history
…e to buffers.
  • Loading branch information
chriskohlhoff committed Oct 22, 2024
1 parent a03e4d6 commit ab3ae0e
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
76 changes: 72 additions & 4 deletions asio/include/asio/buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,38 @@ inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
return static_cast<const const_buffer*>(detail::addressof(b));
}

/// Get an iterator to the first element in a buffer sequence.
template <typename ConvertibleToBuffer>
inline const ConvertibleToBuffer* buffer_sequence_begin(
const ConvertibleToBuffer& b,
constraint_t<
!is_convertible<const ConvertibleToBuffer*, const mutable_buffer*>::value
> = 0,
constraint_t<
!is_convertible<const ConvertibleToBuffer*, const const_buffer*>::value
> = 0,
constraint_t<
is_convertible<ConvertibleToBuffer, mutable_buffer>::value
|| is_convertible<ConvertibleToBuffer, const_buffer>::value
> = 0) noexcept
{
return detail::addressof(b);
}

/// Get an iterator to the first element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_begin(C& c,
constraint_t<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<C, mutable_buffer>::value
> = 0,
constraint_t<
!is_convertible<C, const_buffer>::value
> = 0) noexcept -> decltype(c.begin())
{
return c.begin();
Expand All @@ -347,7 +373,15 @@ template <typename C>
inline auto buffer_sequence_begin(const C& c,
constraint_t<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<C, mutable_buffer>::value
> = 0,
constraint_t<
!is_convertible<C, const_buffer>::value
> = 0) noexcept -> decltype(c.begin())
{
return c.begin();
Expand Down Expand Up @@ -382,12 +416,38 @@ inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
return static_cast<const const_buffer*>(detail::addressof(b)) + 1;
}

/// Get an iterator to one past the end element in a buffer sequence.
template <typename ConvertibleToBuffer>
inline const ConvertibleToBuffer* buffer_sequence_end(
const ConvertibleToBuffer& b,
constraint_t<
!is_convertible<const ConvertibleToBuffer*, const mutable_buffer*>::value
> = 0,
constraint_t<
!is_convertible<const ConvertibleToBuffer*, const const_buffer*>::value
> = 0,
constraint_t<
is_convertible<ConvertibleToBuffer, mutable_buffer>::value
|| is_convertible<ConvertibleToBuffer, const_buffer>::value
> = 0) noexcept
{
return detail::addressof(b) + 1;
}

/// Get an iterator to one past the end element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_end(C& c,
constraint_t<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<C, mutable_buffer>::value
> = 0,
constraint_t<
!is_convertible<C, const_buffer>::value
> = 0) noexcept -> decltype(c.end())
{
return c.end();
Expand All @@ -398,7 +458,15 @@ template <typename C>
inline auto buffer_sequence_end(const C& c,
constraint_t<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<const C*, const const_buffer*>::value
> = 0,
constraint_t<
!is_convertible<C, mutable_buffer>::value
> = 0,
constraint_t<
!is_convertible<C, const_buffer>::value
> = 0) noexcept -> decltype(c.end())
{
return c.end();
Expand Down
29 changes: 29 additions & 0 deletions asio/src/tests/unit/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,17 @@ struct valid_mutable_b
mutable_buffer* end() const { return 0; }
};

struct custom_const_buffer_sequence
{
operator const_buffer() const { return const_buffer(0, 0); }
};

struct custom_mutable_buffer_sequence
{
operator mutable_buffer() const { return mutable_buffer(0, 0); }
operator const_buffer() const { return mutable_buffer(0, 0); }
};

struct invalid_const_a
{
typedef int value_type;
Expand Down Expand Up @@ -624,6 +635,24 @@ void test()
ASIO_CHECK(buffer_sequence_begin(b8) == b8.begin());
ASIO_CHECK(buffer_sequence_end(b8) == b8.end());

ASIO_CHECK(is_const_buffer_sequence<
custom_const_buffer_sequence>::value);
ASIO_CHECK(!is_mutable_buffer_sequence<
custom_const_buffer_sequence>::value);

custom_const_buffer_sequence b11;
ASIO_CHECK(buffer_sequence_begin(b11) == &b11);
ASIO_CHECK(buffer_sequence_end(b11) == &b11 + 1);

ASIO_CHECK(is_const_buffer_sequence<
custom_mutable_buffer_sequence>::value);
ASIO_CHECK(is_mutable_buffer_sequence<
custom_mutable_buffer_sequence>::value);

custom_mutable_buffer_sequence b12;
ASIO_CHECK(buffer_sequence_begin(b12) == &b12);
ASIO_CHECK(buffer_sequence_end(b12) == &b12 + 1);

ASIO_CHECK(!is_const_buffer_sequence<invalid_const_a>::value);
ASIO_CHECK(!is_mutable_buffer_sequence<invalid_const_a>::value);

Expand Down

0 comments on commit ab3ae0e

Please sign in to comment.