diff --git a/asio/include/asio/buffer.hpp b/asio/include/asio/buffer.hpp index 52c812ca17..bd049a170c 100644 --- a/asio/include/asio/buffer.hpp +++ b/asio/include/asio/buffer.hpp @@ -380,12 +380,38 @@ inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b, return static_cast(detail::addressof(b)); } +/// Get an iterator to the first element in a buffer sequence. +template +inline const ConvertibleToBuffer* buffer_sequence_begin( + const ConvertibleToBuffer& b, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + is_convertible::value + || is_convertible::value + > = 0) noexcept +{ + return detail::addressof(b); +} + /// Get an iterator to the first element in a buffer sequence. template inline auto buffer_sequence_begin(C& c, constraint_t< !is_convertible::value - && !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value > = 0) noexcept -> decltype(c.begin()) { return c.begin(); @@ -396,7 +422,15 @@ template inline auto buffer_sequence_begin(const C& c, constraint_t< !is_convertible::value - && !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value > = 0) noexcept -> decltype(c.begin()) { return c.begin(); @@ -431,12 +465,38 @@ inline const const_buffer* buffer_sequence_end(const ConstBuffer& b, return static_cast(detail::addressof(b)) + 1; } +/// Get an iterator to one past the end element in a buffer sequence. +template +inline const ConvertibleToBuffer* buffer_sequence_end( + const ConvertibleToBuffer& b, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + is_convertible::value + || is_convertible::value + > = 0) noexcept +{ + return detail::addressof(b) + 1; +} + /// Get an iterator to one past the end element in a buffer sequence. template inline auto buffer_sequence_end(C& c, constraint_t< !is_convertible::value - && !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value > = 0) noexcept -> decltype(c.end()) { return c.end(); @@ -447,7 +507,15 @@ template inline auto buffer_sequence_end(const C& c, constraint_t< !is_convertible::value - && !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value + > = 0, + constraint_t< + !is_convertible::value > = 0) noexcept -> decltype(c.end()) { return c.end(); diff --git a/asio/src/tests/unit/buffer.cpp b/asio/src/tests/unit/buffer.cpp index 154472bfb5..74557de303 100644 --- a/asio/src/tests/unit/buffer.cpp +++ b/asio/src/tests/unit/buffer.cpp @@ -498,6 +498,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; @@ -626,6 +637,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::value); ASIO_CHECK(!is_mutable_buffer_sequence::value);